day31|LeetCode:● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

文章介绍了三道编程题目,分别是455.分发饼干,使用贪心算法按需分配;376.摆动序列,寻找最长摆动序列的长度,通过维护状态变量判断;53.最大子数组和,通过动态规划找到局部最大和。每道题都提供了代码实现和解题思路。

题目链接:455. 分发饼干

代码

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
      sort(g.begin(), g.end());
      sort(s.begin(), s.end());
      int size = 0;
      int t =0;
      for (int i = 0; i < g.size(); i++) {
          for (int j = t; j < s.size(); j++) {
              if (g[i] <= s[j]) {
                  size++;
                  t = j + 1;
                  break;
              }
          }
      }
      return size;
    }
};

思路

分发饼干按照贪心算法,只需要把最小的饼干分给最小需求或者最大饼干分发给最大需求的人。

局部最优:最小饼干给最小需要的人

推出全局最优:满足这个的人数


题目链接:376. 摆动序列

代码

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if (nums.size() == 1) {
            return 1;
        }
        int count = 0;
        bool usedm = false;
        bool usedn = false;
        for (int i = 0; i < nums.size() - 1; i++) {
            int j = i + 1;
            if (nums[j] > nums[i]) {
               if (usedm == false) {
                   count++;
                   usedm = true;
                   usedn = false;
               }else {
                   continue;
               }
            } else if (nums[j] < nums[i]) {
                if (usedn == false) {
                    count++;
                    usedn = true;
                    usedm = false;
                } else {
                    continue;
                }
            } else if (nums[j] == nums[i]){
                continue;
            }
        }
          
        return count + 1;
    }
};

思路

判断最长摆动的长度

摆动:上一个相差为负,下一个相差为正

可以间隔选择摆动元素,比如连续两个为正,可以跳过一个

当一个元素时候输出1

给予两个bool变量,判断下一次的摆动合法性,这一次是递增就把递增变量的值设为true,下一次必定为递减,部递减就跳过此次循环知道递减为止,递减完,递增bool值设为false,下一次必为递增,反复循环,直到最后

当不符合条件跳过,符合条件+1

 二刷代码

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if (nums.size() == 1) return 1;
        int sum = 0;
        for (int i = 1 ; i < nums.size(); i++) {
            sum += nums[i] - nums[i - 1];
        }
        if (sum == 0) return 1;
//前面就是只有一个点或是一条线的时候的情况,它们的值都为1,其余情况最少为2

        int prediff = 0;
        int curdiff = 0;
        int count = 0;
        for (int i = 1; i < nums.size() - 1; i++) {
            if (nums[i] - nums[i - 1] != 0) prediff = nums[i] - nums[i - 1];
            if (nums[i + 1] - nums[i] != 0) curdiff = nums[i + 1] - nums[i];
            if (prediff * curdiff < 0) {
                count++;
            }
        }
        count += 2;
        return count;
    }
};

二刷解析!

有两种值

1.值为1,当只有一个点,或者点连在一起是一条直线值就是1,没有摆动

2.值至少为2,当只有一个单调线时,只有两个首尾摆动点,当中间有波折的时候,必须加上这个波折的点,如果中间有平坦的线时就跳过这次循环。

波折:两边的符号不一样


题目链接:53. 最大子数组和

代码

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = 0;
        int result = -10000;
        for (int i = 0; i < nums.size(); i++) {
            sum += nums[i];
            if (sum > result) {
                result = sum;
            }
            if (sum <= 0) sum = 0;
        }
        return result;
    }
};

思路

这题是求局部和最长的子序列

所以当相加为负数时候,因为比原来的结果都小,就必定不是我们要找的结果,所以就跳过该元素,从下一个元素重新从0开始.

 局部优先:先求出每个符合条件的最大值就是最大值

因为当遍历到相加为负数后,你从0开始计数还会更大,所以可以跳过这个从0计数

二刷笔记:因为必须要选一个元素,当结果小于0时,就要判断新元素还是这个元素那个负数更大,选大一点的那个负数,如果大于0,就继续加,用另一个变量存储最大数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值