455.分发饼干
本题倒是一遍写出来了... 但怎么说呢,由于两个循环的逻辑是先遍历饼干再遍历小孩,并且是从大到小,所以写出来的代码超级复杂:
class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int max = 0;int j = g.size()-1;for(int i = s.size()-1; i>=0; i--){if(j == -1){break;}if(s[i] >= g[j]){max++;j--;continue;}else{while(j >=0 && s[i] < g[j]){j--;}if(j==-1){break;}else{max++;j--;}}}return max;}
};
看了解析之后倒也能理解循环换过来之后就能简单很多,或者按照我这个循环顺序但是从小的饼干开始也可以很简单就写出来,可是冥思苦想半天也没搞明白为什么。苦思了2年半之后才终于有了一点想法:
1 从胃口大的小孩开始,假设这个小孩没有饼干满足,那么就没有能满足他的饼干了。此时我们可以放心大胆的跳过这个小孩,他已经可以remake了。
2 但如果是从最大的饼干开始,假设队头的小孩胃口比这个饼干还大,但是此时这个饼干的循环是不能跳过的,因为还有可能有别的小孩要吃这个饼干,那么我们就需要在主循环之外再添加新的循环去遍历小孩,复杂也体现在这里。
3 同理,从小饼干开始,假设这个饼干太小,胃口最小的孩子都说“狗都不吃”,那么此时这个饼干我们能放心大胆的拿去喂狗,因为这个饼干已经没人会想去吃了。此时以饼干为主体就可以一遍完成遍历,不需要额外的循环。
4 而如果从小人开始,这个小人发现某个饼干不够他吃,但此时还不能跳过,因为可能大一点的饼干是能满足他的。那么此时我们又需要再建立一个饼干的循环,又绕远了。
所以最终简单的方法如下,直接把卡哥的代码搬过来吧:
class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index = s.size() - 1; // 饼干数组的下标int result = 0;for (int i = g.size() - 1; i >= 0; i--) { // 遍历胃口if (index >= 0 && s[index] >= g[i]) { // 遍历饼干result++;index--;}}return result;}
};
376. 摆动序列
这个题完全会错了意,还以为必须要连续才行呢。错了之后就去GPT了,GPT给出的解法非常的简单:
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {if (nums.size() < 2) {return nums.size();}int up = 1, down = 1;for (int i = 1; i < nums.size(); i++) {if (nums[i] > nums[i - 1]) {up = down + 1;} else if (nums[i] < nums[i - 1]) {down = up + 1;}}return max(up, down);.}
};
这个什么意思呢,我们分情况来讨论下就很清晰了:
1 假设本次是摆动
比如说本次是比上一个值更大的,我们走代码up = down +1。为什么是down而不是up?后面再详细去说。
2 本次单调递增/递减
假设递增,那此时我们的up = down +1,因为down和上一次的值没发生变化,所以up此时也不变。
那么通过这样的一种交错的加法,我们发现,只有在出现摆动的时候,up和down的值才会真正变化,否则不管来多少数都是上一个down/up + 1。用这种方式,就可以很直接的绕过单纯递增,递减和持平的情况,直接计算出摆动的次数。
感觉做贪心的题就像是看剧,一旦知道了谜底,再看内容也变得索然无味了...
53. 最大子序和
本题之前好像做过,但二周目还是犯了几个经典错误:
1 完全没考虑有负数的情况,把max设置成了0,但如果数组是[-3, -2, -1],如果max是0那么返回值也是0,但实际上应该返回-1才对。所以max应该设置成INT_MIN而非0。
2 一开始for循环是这么写的:
for(int i = 0; i < nums.size(); i++){sum += nums[i];if(max < sum){max = sum;}else if(sum <0){sum = 0;}}
但这里 max<sum 和 sum<0 之间并不存在选择关系,导致在[-2,1]这样的例子下,会返回-1。这就是max < sum并且同时sum也小于0,那么此时sum应该进行清空操作,所以应该是两个if才对。
class Solution {
public:int maxSubArray(vector<int>& nums) {int max = INT_MIN;int sum = 0;for(int i = 0; i < nums.size(); i++){sum += nums[i];if(max < sum){max = sum;}if(sum <0){sum = 0;}}return max;}
};