算法学习 | day27/60 分发饼干/摆动序列/最大子序和

一、题目打卡

        1.1 分发饼干

        题目链接:. - 力扣(LeetCode)

// class Solution {
// public:
//     int findContentChildren(vector<int>& g, vector<int>& s) {
//         if(s.empty()) return 0;
//         sort(g.begin(),g.end());
//         sort(s.begin(),s.end());
//         if(s.back() < g[0]) return 0;
//         int i = 0, j = 0;
//         while(s[j] < g[0]) j++; // 找到第一个满足胃口的地方
//         // if(j == s.size()) return 0;
//         int res = 0;
//         // while(i < g.size() && j < s.size()){
//         //     if(g[i] <= s[j]) res++;
//         //     i++;
//         //     j++;
//         // }
//         while(i < g.size() && j < s.size()){
//             if(g[i] <= s[j]){
//                 res++;
//                 i++;
//                 j++;
//             }else j++;
//         }
//         return res;

//         // int i = 0;
//         // // cout << min(g.size(),s.size());
//         // while(i < min(g.size(),s.size()) && s[i] < g[0]) i++;
//         // // if(i == min(g.size(),s.size())) return 0;
//         // int j = i;
//         // for(; j < min(g.size(),s.size()); j++){
//         //     if(s[j] < g[j]) return j;
//         // }
//         // return j - i;
//     }
// };


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

        题目本事不难,我考虑的时候复杂了,但是思路是没有太大问题。

        1.2 摆动序列

        题目链接:. - 力扣(LeetCode)        

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        // if(nums.size() == 1 || (nums.size() == 2 && nums[0] != nums[1])) return nums.size();
        if(nums.size() == 1) return nums.size();
        // if(nums.size() == 2) return 1;
        int i = 0 , j = 1;
        int diff = nums[j] - nums[i];
        // 处理开头全一样的情况
        while(j < nums.size() && diff == 0){
            i++;
            j++;
            if(j == nums.size()) break;
            diff = nums[j] - nums[i];
        }
        int res = 0;
        while(j < nums.size()){
            i++;
            j++;
            if(j == nums.size()){
                res++;
                break;
            }
            if((nums[j] - nums[i]) * diff >= 0) continue;
            else{
                diff = nums[j] - nums[i];
                res++;
            }
        }
        return res + 1;
    }
};

        相比较答案我这个更像是用测试用例不断改进出来的一个版本,非常冗余,不过既然贪心没有固定的解法,那也就当做是这个题目的非最优解吧,答案贴在下面:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if (nums.size() <= 1) return nums.size();
        int curDiff = 0; // 当前一对差值
        int preDiff = 0; // 前一对差值
        int result = 1;  // 记录峰值个数,序列默认序列最右边有一个峰值
        for (int i = 0; i < nums.size() - 1; i++) {
            curDiff = nums[i + 1] - nums[i];
            // 出现峰值
            if ((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)) {
                result++;
                preDiff = curDiff; // 注意这里,只在摆动变化的时候更新prediff
            }
        }
        return result;
    }
};

        1.3 最大子数组和(答案思路)

        题目链接:. - 力扣(LeetCode)

// class Solution {
// public:
//     int maxSubArray(vector<int>& nums) {
//         if(nums.size() == 1) return nums[0];
//         int i = 0, last_max = INT_MIN, max_tmp = nums[0];
//         for(;i<nums.size() - 1 ; i++){
//             if(nums[i + 1] + nums[i] >= 0){
//                 if(max_tmp < 0)
//                 max_tmp += nums[i+1];
//             }
//             else{
//                 last_max = max(last_max,max_tmp);
//                 // max_tmp = 0;
//                 max_tmp = nums[i + 1];
//             }
//         }
//         if(last_max == INT_MIN) return max_tmp;
//         return last_max;
//     }
// };

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = 0;
        int res = INT_MIN;
        for(int i = 0 ; i < nums.size();i++){
            sum += nums[i];
            if(sum > res) res = sum; // 这个必须要放前面,不然只有一个数字的时候就会返回0,而且初始化res一定要是最小的int
            if(sum <= 0) sum = 0;
        }
        return res;
    }
};

        这个题目借助了答案的思路,所以也没什么好讲的,我发现我的思路就是贪心的不够贪?或者是我的一个局部最优的选择不太正确,我选择的是步长为正数的不断累加,但是这样会出现一个问题就是,在遇到步长为负数的时候,我的一个 tmp_max 值的更新是一个问题,而且计算步长会存在一个重复计算值的问题,反正没解决,我也不想浪费太多时间,这个题目应该以动态规划的思想可以理解的更好,先放下吧。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值