代码随想录第三十一天|贪心算法理论基础、Leetcode455.分发饼干、Leetcode376. 摆动序列、Leetcode53. 最大子序和
贪心算法理论基础
文章链接:贪心算法理论基础
贪心的实质是不停的取局部最优,然后组成全局最优。没有具体的一定可以用贪心的类型,也没有非常具体的模板,只能说自己去推导一下感觉可以利用局部最优得到全局最优,那就用贪心。
贪心算法有个大概的流程:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
这四步其实很抽象,做的时候就牢记局部最优->全局最优就行了
Leetcode455.分发饼干
太简单了,不知道说啥好,根本不知道贪心用上没
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
int count=0;
sort(g.begin(),g.end());
sort(s.begin(),s.end());
for(int i=0,j=0;i<g.size()&&j<s.size();i++,j++){
while(j<s.size()-1&&s[j]<g[i]){
j++;
}
if(s[j]>=g[i]) count++;
}
return count;
}
};
Leetcode376. 摆动序列
一下就不简单起来了,这个题目最主要的就是梳理清楚情况,然后画图出来再做考虑。
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size()==1) return 1;
if(nums.size()==2 && nums[0]!=nums[1]) return 2;
int cursub=0,presub=0,result=1;
for(int i=0;i<nums.size()-1;i++){
cursub=nums[i+1]-nums[i];
if((presub<=0&&cursub>0)||(presub>=0&&cursub<0)){
result++;
presub=cursub;
}
}
return result;
}
};
Leetcode53. 最大子序和
还是dp用着顺手,定义dp[i]
为以nums[i]
为结尾元素的最大和,形成了一个On+On的方法,由于必定遍历一遍所以时间复杂度就这样了,不过空间复杂度只能说一般
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int>dp(nums.size(),0);
dp[0]=nums[0];
int result=dp[0];
for(int i=1;i<nums.size();i++){
dp[i]=max(dp[i-1]+nums[i],nums[i]);
result=max(result,dp[i]);
}
return result;
}
};
用贪心算法,。。实际上我看不出来是不是贪心,就感觉普通的解题而已。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int result = INT32_MIN;
int temp = 0;
for (int i = 0; i < nums.size(); i++) {
temp+=nums[i];
result=max(result,temp);
if(temp<0) temp=0;
}
return result;
}
};