leetcode算法-最长和谐子序列

这两天正在忙实习找工作,晚上就抽时间写写算法,放松一下子

一、题目

和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是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倍左右。。。。。。

原文地址:https://www.cnblogs.com/mcjhcnblogs/p/13096111.html