这两天正在忙实习找工作,晚上就抽时间写写算法,放松一下子
一、题目
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1。
现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度。
示例 1:
输入: [1,3,2,2,5,2,3,7]
输出: 5
原因: 最长的和谐数组是:[3,2,2,2,3].
说明: 输入的数组长度最大不超过20,000.
二、解题思路
此题的意思,无非就是在在排好序的数组中,找到最大值和最小值相差一的,且距离最远的两个元素,加一即可
所以,首先对数组进行排序,排序算法本人了解比较快的又相对简单的还是快速排序,所以就用快速排序先进行排序,之后采用双层循环,第一层从左到右遍历数组中的元素,第二层从右到左遍历元素,直到找出比外层循环大一的元素(没有就循环完),此时计算长度,与原来长度对比,选出最大的,跳出本次循环,直到结束。
注意:二层循环不可以从左向右循环,原因是如果最大的数有好几个相同的,就会处理着很麻烦。
三、代码:
public static void main(String[] args) { int[] array = new int[] { 1, 3, 2, 2, 5, 2, 3, 7 }; System.out.println(getHarmoniousArrayLength(array)); } public static int getHarmoniousArrayLength(int[] array) { // 首先对数组进行有序化 quickSort(array, 0, array.length - 1); // 存储最大数量 int max = 0; for (int i = 0; i < array.length - 1; i++) { for (int j = array.length - 1; j > i; j--) { // 判断是否符合条件 if (array[i] + 1 == array[j]) { // 计算长度 int result = j - i + 1; // 选出长度最大的差值 if (result > max) { max = result; break; } } } } return max; } // 快速排序 public static void quickSort(int[] array, int low, int high) { // 最小数组 if (low < high) { int i = low; int j = high; int middle = array[low]; // 进行判断,并且互换 while (i < j) { // 寻找出左边的不合适元素 while (i < j && array[j] >= middle) { j--; } // 寻找出右边的不合适元素 while (i < j && array[i] <= middle) { i++; } if (i < j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } // 将基准和最后指针位置的数进行互换 array[low] = array[j]; array[j] = middle; // 将基准数左边和右边进行同样的操作 quickSort(array, low, j - 1); quickSort(array, j + 1, high); } }
效率截图:
四、优化算法
第二天重新看题,发现内循环如果倒叙虽然方便了不少,但是对于较长的数组说,遍历的无用数据过多,造成时间的大量浪费,采用正序遍历,当数字不为第一个数或者不为第一个数加一时,就跳出循环,判断跳出循环位置的前一个数是否时循环外层数组加一,如果按正常走完,没跳出循环,则要进行相同的判断。
代码如下:
// 首先对数组进行有序化 quickSort(array, 0, array.length - 1); // 存储最大数量 int max = 0; for (int i = 0; i < array.length - 1; i++) { int j = 0; for (j = i+1; j < array.length; j++) { if(j == array.length - 1) { } // 判断是否符合条件 if (array[i] != array[j] && array[i]+1 != array[j]) { if(array[i] + 1 == array[j - 1]) { // 计算长度 int sum = j - i; if(max < sum) { max = sum; } } break; } } // 统一处理 if(array[i] + 1 == array[j - 1]) { // 计算长度 int sum = j - i; if(max < sum) { max = sum; } } } return max; } // 快速排序 public static void quickSort(int[] array, int low, int high) { // 最小数组 if (low < high) { int i = low; int j = high; int middle = array[low]; // 进行判断,并且互换 while (i < j) { // 寻找出左边的不合适元素 while (i < j && array[j] >= middle) { j--; } // 寻找出右边的不合适元素 while (i < j && array[i] <= middle) { i++; } if (i < j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } // 将基准和最后指针位置的数进行互换 array[low] = array[j]; array[j] = middle; // 将基准数左边和右边进行同样的操作 quickSort(array, low, j - 1); quickSort(array, j + 1, high); } }
效率截图:
效率提升了30倍左右。。。。。。