「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」
题目
和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 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
};
写在最后
刚开始在掘金更新文章,如有不足使出请不吝指教;不足之处,多多见谅。