前言说明
算法学习,日常刷题记录。
题目连接
题目内容
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1。
现在,给你一个整数数组nums,请你在所有可能的子序列中找到最长的和谐子序列的长度。
数组的子序列是一个由数组派生出来的序列,它可以通过删除一些元素或不删除元素、且不改变其余元素的顺序而得到。
示例1:
输入:nums = [1,3,2,2,5,2,3,7]
输出:5
解释:最长的和谐子序列是[3,2,2,2,3]
示例2:
输入:nums = [1,2,3,4]
输出:2
示例3:
输入:nums = [1,1,1,1]
输出:0
提示:
1 <= nums.length <= 2 * 10^4
-10^9 <= nums[i] <= 10^9
分析过程
思路:哈希表法。
第一步
定义集合map,保存数组中每个数字出现的次数。
第二步
遍历数组nums,统计数组中每个数字出现的次数,用集合map的getOrDefault方法。
第三步
定义最长的和谐子序列的长度maxLength,遍历集合map中的key,即寻找以key作为最小值的子序列。
每次遍历时:
集合map寻找是否存在比当前key大1的key,因为和谐子序列是最大值和最小值的差正好是1,若存在,那么当前和谐子序列的长度是key的次数和key+1的次数之和,而子序列不一定连续,所以任意两个最大值和最小值都可以去构造出和谐子序列,然后比较两者的值,取较大值赋给最长的和谐子序列的长度maxLength。
例如:nums = [1,3,2,2,5,2,3,7]
那么,1有1个,3有2个,2有3个,5有1个,7有1个。
当key为1时,寻找2,1和2组合成和谐子序列,把其他多余的数去掉,此序列的长度就是1的个数和2的个数,即1+3=4。
当key为3时,寻找4,3和4组合成和谐子序列,把其他多余的数去掉,此序列的长度就是3的个数和4的个数,因为没有4,所以不存在和谐子序列。
当key为2时,寻找3,2和3组合成和谐子序列,把其他多余的数去掉,此序列的长度就是2的个数和3的个数,即3+2=5。
当key为5时,寻找6,5和6组合成和谐子序列,把其他多余的数去掉,此序列的长度就是5的个数和6的个数,因为没有6,所以不存在和谐子序列。
当key为7时,寻找8,7和8组合成和谐子序列,把其他多余的数去掉,此序列的长度就是7的个数和8的个数,因为没有8,所以不存在和谐子序列。
所以综上所述,和谐子序列长度分别为4和5,最大和谐子序列为5。
第四步
遍历集合map结束后,返回最长的和谐子序列的长度maxLength。
解答代码
class Solution {
public int findLHS(int[] nums) {
// 哈希表法
// 定义集合map,保存数组中每个数字出现的次数
Map<Integer, Integer> map = new HashMap<>();
// 遍历数组,统计数组中每个数字出现的次数
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
// 定义最长的和谐子序列的长度
int maxLength = 0;
// 遍历集合map中的key
for (int key : map.keySet()) {
// 寻找是否存在比当前key大1的key,因为和谐子序列是最大值和最小值的差正好是1
if (map.containsKey(key + 1)) {
// 当前和谐子序列的长度是key的次数和key+1的次数之和,因为子序列不一定连续,所以任意两个最大值和最小值都可以去构造出和谐子序列
maxLength = Math.max(maxLength, map.get(key) + map.get(key + 1));
}
}
// 返回最长的和谐子序列的长度
return maxLength;
}
}
提交结果
执行用时15ms,时间击败67.21%的用户,内存消耗39.4MB,空间击败45.61%的用户。
运行结果原文链接
原文链接:最长和谐子序列
网友评论