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

题目链接:455. 分发饼干

代码

class Solution {
public:
    int findContentChildren(vector& g, vector& 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;
    }
};

思路

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

day31|LeetCode:● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和_第1张图片

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

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


题目链接:376. 摆动序列

代码

class Solution {
public:
    int wiggleMaxLength(vector& 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& 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& 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,就继续加,用另一个变量存储最大数

你可能感兴趣的:(代码随想录一刷,leetcode,算法,数据结构,c++)