初步看到题,还以为简单,不过仔细想想也不简单。本题解题思路采用滑动窗口方法,用两个指针构成一个窗口,满足条件的元素进窗口,不满足条件移动窗口。下面就是详细的解题思路,有五个元素1,2,2,3,4
1,采用滑动窗口的前提是数组元素是有序的,首先对数组排序
2,begin就是窗口的左边,end就是窗口的右边,元素进窗口的条件是arr[end] - arr[begin] = 1,因为经过排序后数组是有序的,最右边就是最大的,最左边是最小的
3,如果右边的元素满足条件,end++,每进一个元素则与当前记录最长和谐序列的进行比较,如果当前的窗口元素比ret大,则更新ret
4,如果右边的元素不满足窗口条件了,则移动左边的窗口即begin++,知道找到满足建立窗口的元素
下面看代码
int cmp(int *a, int *b)
{
return *a - *b;
}
int findLHS(int* nums, int numsSize)
{
qsort(nums,numsSize,sizeof(int),cmp);
int begin = 0;
int end = 0;
int ret = 0;
for(end=0; end<numsSize; end++)
{
while(nums[end] - nums[begin] > 1)
begin++;
if(nums[end] - nums[begin] == 1)
ret = end-begin+1 > ret ? end-begin+1:ret;
}
return ret;
}
该题也可以用哈希来做,第一次遍历建立哈希表,第二次遍历找出 x和x+1的最值
typedef struct {
int key;
int val;
UT_hash_handle hh;
} Hash;
int findLHS(int* nums, int numsSize){ // 哈希表
Hash *hash = NULL;
Hash *tmp;
// 遍历数组,建立哈希表
for (int i = 0; i < numsSize; i++) {
HASH_FIND_INT(hash, &nums[i], tmp);
if (tmp == NULL) {
tmp = (Hash*)malloc(sizeof(Hash));
tmp->key = nums[i];
tmp->val = 1;
HASH_ADD_INT(hash, key, tmp);
} else {
tmp->val++;
}
}
int ret = 0;
// 遍历哈希表,计算x 和 x+1出现的次数之和,并求最值
Hash *iter, *tmp1;
HASH_ITER(hh, hash, iter, tmp) {
if (iter) {
int nextKey = iter->key + 1;
HASH_FIND_INT(hash, &nextKey, tmp1);
if (tmp1) {
ret = fmax(ret, iter->val + tmp1->val);
}
}
}
// 释放内存
HASH_ITER(hh, hash, iter, tmp) {
HASH_DEL(hash, iter); // 节点从哈希表中摘掉(内存并没有释放)
free(iter); // 释放该节点的内存
}
return ret;
}