day31|LeetCode:● 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,就继续加,用另一个变量存储最大数
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
给定一个整数数组 nums 和一个目标值 target,要求在数组中找出两个数的和等于目标值,并返回这两个数的索引。 思路1:暴力法 最简单的思路是使用两层循环遍历数组的所有组合,判断两个数的和是否等于目标值。如果等于目标值,则返回这两个数的索引。 此方法的时间复杂度为O(n^2),空间复杂度为O(1)。 思路2:哈希表 为了优化时间复杂度,可以使用哈希表来存储数组中的元素和对应的索引。遍历数组,对于每个元素nums[i],我们可以通过计算target - nums[i]的值,查找哈希表中是否存在这个差值。 如果存在,则说明找到了两个数的和等于目标值,返回它们的索引。如果不存在,将当前元素nums[i]和它的索引存入哈希表中。 此方法的时间复杂度为O(n),空间复杂度为O(n)。 思路3:双指针 如果数组已经排,可以使用双指针的方法来求解。假设数组从小到大排,定义左指针left指向数组的第一个元素,右指针right指向数组的最后一个元素。 如果当前两个指针指向的数的和等于目标值,则返回它们的索引。如果和小于目标值,则将左指针右移一位,使得和增大;如果和大于目标值,则将右指针左移一位,使得和减小。 继续移动指针,直到找到两个数的和等于目标值或者左指针超过了右指针。 此方法的时间复杂度为O(nlogn),空间复杂度为O(1)。 以上三种方法都可以解决问题,选择合适的方法取决于具体的应用场景和要求。如果数组规模较小并且不需要考虑额外的空间使用,则暴力法是最简单的方法。如果数组较大或者需要优化时间复杂度,则哈希表或双指针方法更合适。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值