[路飞]_夜.最长和谐子序列

627 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

594. 最长和谐子序列

题目

和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 1 。

现在,给你一个整数数组 nums ,请你在所有可能的子序列中找到最长的和谐子序列的长度。

数组的子序列是一个由数组派生出来的序列,它可以通过删除一些元素或不删除元素、且不改变其余元素的顺序而得到。

示例 1:


输入:nums = [1,3,2,2,5,2,3,7]
输出:5
解释:最长的和谐子序列是 [3,2,2,2,3]

解题思路

思路1 排序

最直观的想法,对数组排序,将排序后的数组找到前后相差为1的长度;因为数组是已经过排序的,所以相差为1的数组元素已经相邻;只需要统计数字不同且相邻并且两数之差为1两个数长度即可得到正确答案;

分析时间复杂度:因为需要对数组进行排序,所以时间复杂度最低是O(logN)

思路2 哈希表

简单问题简单解决;

枚举数组中的每一个元素,对于当前枚举的元素 x,它可以和x-1或者x+1组成和谐子序列。

那么是不是找到数组中x、x-1、x+1的数量就可以找到最大和谐数组的长度?

如何记录保存数组中每个数组出现的字数并缺获取比较方便呢? 首先想到哈希表 哈希表最适合保存元素数量?

在本题中可以申请额外空间map;

枚举数组,如果数组中元素已经在map中,将map中该元素的数量+1;枚举完数组,即可统计到数组中每个元素出现的额次数

这里举个栗子更容易理解

比如数组num = [1,3,2,2,5,2,3,7] 假设哈希表为map; 遍历数组num得到map为

const map = {
    1:1,
    2:3,
    3:2,
    5:1,
    7:1
}

解释:数组num中出现了1个1,3个2,2个3,1个5,1个7 1+3= 4; 3+2 = 5; 明显,全部由2、3组成的数组是最长的和谐数组 2+3 = 5; 根据上述思路,编辑代码如下

代码

var findLHS = function(nums) {
    const map = {};
    nums.forEach(n=>{
        map[n] = (map[n]||0)+1
    })
    let result = 0;
    Object.keys(map).forEach(k=>{
        k = Number(k)
        const c = map[k];
        const after =c && map[k-1]? c + map[k-1]: 0;
        const next = c &&  map[k+1] ? c  +map[k+1]: 0;
        result = Math.max(result,after,next)
    })
    return result
};

写在最后

刚开始在掘金更新文章,如有不足使出请不吝指教;不足之处,多多见谅。