最长和谐子序列
题目
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是 1 。
给一个整数数组 nums ,在所有可能的子序列中找到最长的和谐子序列的长度。
数组的子序列是一个由数组派生出来的序列,它可以通过删除一些元素或不删除元素、且不改变其余元素的顺序而得到。
示例
输入:nums = [1,3,2,2,5,2,3,7]
输出:5
解释:最长的和谐子序列是 [3,2,2,2,3]
题解
方法 1 枚举
由于和谐数组中最大值和最小值差值正好为 1 ,可以采用枚举的方法,对于当前元素 x ,可以找出 x+1 与其组成和谐子序列。为了便于查找,可以先对数组进行排序,从左到右遍历找到相邻两个元素差为 1 的子序列即可。遍历时采用滑动窗口的思想,设置指针 begin 指向第一个子序列的第一个元素,end 指向第二个子序列的末尾元素,若满足两指针指向元素差为 1 ,则窗口成立,当前的和谐子序列长度为 end-begin+1 。
方法 2 哈希表
题目要求找到最长的和谐子序列,由于可以任意删除其中的元素,故子序列在原数组中不一定连续,则转换为找出元素 x 和 x+1 出现次数最多的子序列。因此,可以采用哈希表存储每个元素及其出现的次数,和谐子序列长度为 x 和 x+1 出现次数之和。
代码
方法 1 枚举
class Solution {
public:
int findLHS(vector<int>& nums) {
//只需要输出和谐子序列长度,排序不影响结果
sort(nums.begin(),nums.end());
int n=nums.size();
int begin=0,res=0;
for(int end=0;end<n;++end){
//找出以end为序列末尾的满足nums[end]-nums[begin]<=1的begin
while(nums[end]-nums[begin]>1){
begin++;
}
//找出最长的和谐子序列
if(nums[end]-nums[begin]==1){
res=max(res,end-begin+1);
}
}
return res;
}
};
方法 2 哈希表
class Solution {
public:
int findLHS(vector<int>& nums) {
unordered_map<int,int> cnt;
for(int num:nums){
cnt[num]++;
}
int res=0;
for(auto [key,val]:cnt){
//判断map中是否存在键值为key+1的键值对
if(cnt.count(key+1)){
res=max(res,val+cnt[key+1]);
}
}
return res;
}
};