LeetCode 455、376 贪心算法(一)

120 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

本文包含以下几题:

  1. 现有几个孩子,孩子对应g数组,数组中的值为孩子的胃口,s数组代表饼干的尺寸,现将饼干分发给孩子,要求满足尽可能多的孩子,返回可满足的孩子的最大值。
  2. 摆动序列。前后元素之差正负交替的数列为摆动序列,先给定一个数组,要求返回作为摆动序列的最长子序列的长度。

解题思路

LeetCode 455、分发饼干

本题是一道经典的贪心算法题,我们要满足尽可能多的孩子,首先我们应该对饼干和孩子胃口进行从小到大排序,这样便于分析,因为一个饼干只能分给一个孩子,无论其胃口是否小于饼干,那么我们就可以根据小饼干首先满足小胃口的孩子或者大饼干首先满足大胃口孩子这两种思路来解题。

两种思路移动的序列并不相同,具体来说:

  • 小饼干优先满足小胃口孩子:此时我们需要固定孩子,移动饼干,只有当饼干大小满足孩子胃口的时候才能移动孩子。
  • 大饼干优先满足大胃口孩子:此时我们需要固定饼干,只有当当前孩子胃口小于等于饼干时才移动饼干,即消耗饼干。

根据上述思路可得第一种代码如下:

public int findContentChildren(int[] g, int[] s) {
    Arrays.sort(g);
    Arrays.sort(s);
    int count = 0;
    int start = 0;
    for(int i=0;i<s.length&&start<g.length;i++){
        if(s[i]-g[start]>=0){
            count++;
            start++;
        }
    }
    return count;
}

第二种代码如下:

public int findContentChildren(int[] g, int[] s) {
    Arrays.sort(g);
    Arrays.sort(s);
    int count = 0;
    int start = s.length-1;
    for(int i=g.length-1;i>=0&&start>=0;i--){
        if(s[start]-g[i]>=0){
            count++;
            start--;
        }
    }
    return count;
}

LeetCode 376、摆动序列

本题也是贪心的思路,实际我们不需要关心具体删除哪个结点,我们只需要保证每次的差值结果都是有效的即可,什么为有效?即当前差值和前一次有效差值为相反的。

从前往后遍历即可得到最终答案:

public int wiggleMaxLength(int[] nums) {
    int count = 1;
    int curDiff = 0;
    int preDiff = 0;
    for(int i=1;i<nums.length;i++){
        curDiff = nums[i]-nums[i-1];
        if((curDiff>0&&preDiff<=0)||(curDiff<0&&preDiff>=0)){
            count++;
            preDiff = curDiff;
        }
    }
    return count;
}