C语言----最长和谐子序列

         初步看到题,还以为简单,不过仔细想想也不简单。本题解题思路采用滑动窗口方法,用两个指针构成一个窗口,满足条件的元素进窗口,不满足条件移动窗口。下面就是详细的解题思路,有五个元素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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ftzchina

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值