贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。
不用花心思去研究其规律, 没有思路就立刻看题解。
基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。
学完贪心之后再去看动态规划,就会了解贪心和动规的区别。
详细布置
理论基础
455.分发饼干
https://programmercarl.com/0455.%E5%88%86%E5%8F%91%E9%A5%BC%E5%B9%B2.html
Tips:很直观的想法,将两个数组排序然后逐个进行比较即可。
我的题解:
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(); ){
if(s[j] >= g[i]){
count++;
i++;
j++;
}
else{
j++;
}
}
return count;
}
};
376. 摆动序列
https://programmercarl.com/0376.%E6%91%86%E5%8A%A8%E5%BA%8F%E5%88%97.html
Tips:这道题不管怎么样,答案最少也是1(因为可以取只有一个元素的子序列),剩下的就是条件判断了。
我的题解:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size() == 1){
return 1;
}
int flag = 0;
int count = 1;
for(int i = 1; i< nums.size(); i++){
if(flag == 0){
if(nums[i] - nums[i-1] > 0){
flag = 1;
count++;
}
else if(nums[i] - nums[i-1] < 0){
flag = -1;
count++;
}
}
else if(flag == -1){
if(nums[i] - nums[i-1] > 0){
flag = 1;
count++;
}
}
else if(flag == 1){
if(nums[i] - nums[i-1] < 0){
flag = -1;
count++;
}
}
}
return count;
}
};
53. 最大子序和
https://programmercarl.com/0053.%E6%9C%80%E5%A4%A7%E5%AD%90%E5%BA%8F%E5%92%8C.html
Tips:
贪心贪的是哪里呢?
如果 -2 1 在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方!
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
从代码角度上来讲:遍历nums,从头开始用count累积,如果count一旦加上nums[i]变为负数,那么就应该从nums[i+1]开始从0累积count了,因为已经变为负数的count,只会拖累总和。
这相当于是暴力解法中的不断调整最大子序和区间的起始位置。
我的题解:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum = 0;
int max = INT_MIN;
for(int i = 0; i< nums.size(); i++){
sum += nums[i];
max = max > sum ? max : sum;
if(sum < 0){
sum = 0;
}
}
return max;
}
};
标签:count,nums,E5%,++,31,455,53,int,flag
From: https://www.cnblogs.com/GavinGYM/p/17096924.html