好久没有这种一道题都做不出来的崩溃了。。。
455.分发饼干
初始思路:
首先对数组进行排序,然后使用最小可以满足孩子需求的饼干,去喂给孩子,这样就可以让更多的孩子满足有饼干吃。
class Solution {
public int findContentChildren(int[] g, int[] s) {
int result = 0;
int i = 0;
int j = 0;
Arrays.sort(g);
Arrays.sort(s);
while(i<g.length&&j<s.length){
if (s[j]<g[i]){j++;}
else if(s[j]>=g[i]){j++;i++;}
}
result = i;
return result;
}
}
题解复盘:
这里的题解参考了力扣中的题解,因为思路差不多易于理解。
贪心策略:我们每次从剩下的孩子中,找出胃口最小的孩子,给他能满足他胃口的最小尺寸饼干即可,这样我们得到的分配方案,是满足孩子的个数最大的。
class Solution {
public int findContentChildren(int[] g, int[] s) {
// 将胃口和饼干排序
Arrays.sort(g);
Arrays.sort(s);
// 孩子的数量
int n = g.length;
// 饼干的数量
int m = s.length;
// 记录结果
int res = 0;
for(int i = 0; i < m; i++){
// 从胃口小的开始喂
if(res < n && g[res] <= s[i]){
res += 1;
}
}
return res;
}
}
作者:编程文青李狗蛋
链接:https://leetcode.cn/problems/assign-cookies/solutions/2103923/acm-xuan-shou-tu-jie-leetcode-fen-fa-bin-wnql/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
大概理解一下就是,for循环遍历的是饼干,如果当前饼干不足以满足当前小孩的胃口,就i++,看看下一块饼干是否可以满足当前小孩的胃口,如果满足res+1,代表已经满足一个小孩的要求,并且res+1同时代表指针移动到下一个小孩,看看是否可以满足其需求,此处还需注意,满足小孩的个数一定需要小于小孩本身的个数。
376.摆动序列
初始思路:
其实感觉对于示例1和示例3都比较好解决,因为只需要判断当前整个序列是否满足摆动序列,而无需考虑删除元素,对于序列2删除元素从而获得最小的摆动子序列实在是不是很理解如何操作。
题解复盘:
感觉这个示例二的解释也太误导了,正确的理解思路是:
贪心思路:
思路上是我删除单调坡度上的节点,这个坡度上我就有两个局部峰值,当我拥有最多的局部峰值,我从而就拥有了最长的摆动序列。
实际操作上是其实连删除的操作都不用做,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)
在实际操作中需要注意三种特殊情况:
1)平坡:
(preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)
2)首尾:默认最右面有一个峰值并且为最左添加平坡,这样首尾就可以使用相同的计算规则同其他数据点。
相同数字连续 的时候, prediff = 0 ,curdiff < 0 或者 >0 也记为波谷。
那么为了规则统一,针对序列[2,5],可以假设为[2,2,5],这样它就有坡度了即 preDiff = 0,如图:
针对以上情形,result 初始为 1(默认最右面有一个峰值),此时 curDiff > 0 && preDiff <= 0,那么 result++(计算了左面的峰值),最后得到的 result 就是 2(峰值个数为 2 即摆动序列长度为 2)
3)平坡2.0
只需要在 这个坡度 摆动变化的时候,更新 prediff 就行,这样 prediff 在 单调区间有平坡的时候 就不会发生变化,造成我们的误判。
class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) {
return nums.length;
}
//当前差值
int curDiff = 0;
//上一个差值
int preDiff = 0;
int count = 1;
for (int i = 1; i < nums.length; i++) {
//得到当前差值
curDiff = nums[i] - nums[i - 1];
//如果当前差值和上一个差值为一正一负
//等于0的情况表示初始时的preDiff
if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
count++;
preDiff = curDiff;
}
}
return count;
}
}
53.最大子数组和
初始思路:
很混乱,可以通过运行示例,但是无法全部AC。
题解复盘:
如果当前的和是正数,肯定会对后面的数值起到增益作用,所以保留。
如果当前的和是负数,肯定会对后面的数值起到削减作用,不如直接从0开始。(加一个负数不如加一个0)
class Solution {
public int maxSubArray(int[] nums) {
int sum = 0;
int result = Integer.MIN_VALUE;
for(int i = 0;i<nums.length;i++){
sum = sum+nums[i];
result = sum>result?sum:result;
if(sum<0){sum=0;}
}
return result;
}
}