代码随想录算法训练营第31天 | 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

贪心理论: 局部最优 -> 整体最优

 

“ 贪心其实就是没有什么规律可言,所以了解贪心算法 就了解它没有规律的本质就够了。 

不用花心思去研究其规律, 没有思路就立刻看题解

基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。  

学完贪心之后再去看动态规划,就会了解贪心和动规的区别。”

没有策略可以判断贪心是否行得通。可以先试一试贪心,不可行就去做dp

关于贪心是否需要推导:贪心没有套路,说白了就是常识性推导+举反例

代码随想录算法训练营第31天 | 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和_第1张图片

----  -----  -----  -----  -----  ------  -------  ------  ----  ----

 #455 分发饼干 10min 

int findContentChildren(vector& g, vector& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());

        int cnt=0;

        int idxg=0; int idxs=0;
        for(idxg=0; idxg

两个思路,我这个是小饼干先喂给小胃口。还有一个是大饼干先给大胃口

我上面写的好绕,用饼干循环套胃口循环会不那么绕:

int findContentChildren(vector& g, vector& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int idxg=0;
        for(int idxs=0; idxs=g[idxg]){
                idxg++;
            }
        }
        return idxg;
    }

#376 摆动序列 Medium

做了好久,40-50min,还是没做出来学的随想录的。我自己想的贪心是,下一个就选第一个大小趋势对的,比如1后面第一个比他大的是17,就选17,17后面第一个比他小的是5. 写了很久之后才发现我这个方法不对。其实也不好证明为啥不对,gpt说“如果早期选择了某个大数,可能会导致后面无法选择到更多的摆动子序列” 总之就是不对!记住好了 

代码随想录算法训练营第31天 | 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和_第2张图片

随想录的思路我觉得用图理解非常好理解,大意是删掉单调区间中间的,也要考虑平坡

代码随想录算法训练营第31天 | 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和_第3张图片

所以就选择了图上8个中四个可以被选入的图案(我觉得按我画图比随想录写的好理解)

这时会写出如下代码:

int wiggleMaxLength(vector& nums) {
        if(nums.size()==1) return 1;

        int diffnow=0;
        int diffprev=0;
        int cnt=1;

        for(int i=0;i+1=0 && diffnow<0)||(diffprev<=0 && diffnow>0)){
                cnt++;
            }
        diffprev=diffnow;
            
        }
        return cnt;
    }

最tricky的地方来了

代码随想录算法训练营第31天 | 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和_第4张图片

于是考虑到这个特殊情况,把更新diff放到if摇摆中,就对了,ac代码: 

int wiggleMaxLength(vector& nums) {
        if(nums.size()==1) return 1;

        int diffnow=0;
        int diffprev=0;
        int cnt=1;

        for(int i=0;i+1=0 && diffnow<0)||(diffprev<=0 && diffnow>0)){
                cnt++;
                diffprev=diffnow;
            }
        }
        return cnt;
       
    }

#53 最大子序和 思路难想 想了20min想不出,看随想录吧

这题O n^2暴力会TLE

一直想不清局部最优在哪,局部最优在:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”

比如当前连续和为-2,下一个数为1,那还不如放弃之前的和-2,直接从1开始计算还大一些呢。而且就算下一个元素是负数也行。比如当前连续和为-2,下一个是-3,如果继续加就成-5了,还不如从-3开始

另一个关键是,要先记录最大的和,再把他归零,因为有可能最大的就已经是负的了,那样结果就是0,就不对

int maxSubArray(vector& nums) {
        int result = INT_MIN;
        int count = 0;
        for (int i = 0; i < nums.size(); i++) {
            count += nums[i];
            if (count > result) { 
                result = count;
            }
            if (count <= 0) count = 0; //这句要放后面
        }
        return result;
    }

你可能感兴趣的:(代码随想录一刷,算法,贪心算法)