day27的任务是贪心算法,这个没有模板可以套,不像二叉树和回溯。个人觉得确实想不到就是想不到,先练练试试吧。
1.贪心的理论基础:代码随想录
带着问题看:
贪心是什么?从局部最优解找全局最优解的过程。
贪心可以解决什么问题?
贪心和动态规划的区别。
2.分发饼干:代码随想录
力扣链接:. - 力扣(LeetCode)
其实就是排个序然后保证大份饼干尽量喂给大胃口。但是注意随想录的两种解法,一个是遍历大胃口,一个是遍历饼干,区别一下谁用for,谁用if,为什么?注意细节。
class Solution {
// 思路1:优先考虑饼干,小饼干先喂饱小胃口
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int start = 0;
int count = 0;
for (int i = 0; i < s.length && start < g.length; i++) {
if (s[i] >= g[start]) {
start++;
count++;
}
}
return count;
}
}
class Solution {
// 思路2:优先考虑胃口,先喂饱大胃口
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int count = 0;
int start = s.length - 1;
// 遍历胃口
for (int index = g.length - 1; index >= 0; index--) {
if(start >= 0 && g[index] <= s[start]) {
start--;
count++;
}
}
return count;
}
}
3.摆动序列:代码随想录
力扣链接:. - 力扣(LeetCode)
脑子模拟一下也很容易出过程,只要去掉中间不符合的点,剩下的都是结果,注意可以用计数器,而不用真正移除元素。
随想录的解题思路,大概分为:默认最右为一个摆动元素,数组可能的情况是什么,分为三类,上下坡中有平坡,数组首尾怎么算(包含长度小于2的情况),单调坡中有平坡,其中单调坡中有平坡比较复杂,注意解题代码中if代码块中的语句,品味一下preDiff = curDiff放在if里和if外面有什么区别。
代码如下:
/**
* 摆动序列
*
* https://leetcode.cn/problems/wiggle-subsequence/
*/
public class _27_2WobbleSequence {
public static int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) {
return nums.length;
}
int result = 1;
int preDiff = 0;
int curDiff = 0;
for (int i = 1; i < nums.length; i++) {
//得到当前差值
curDiff = nums[i] - nums[i - 1];
//如果当前差值和上一个差值为一正一负
//等于0的情况表示初始时的preDiff
if ((preDiff >= 0 && curDiff < 0) || (preDiff <= 0 && curDiff > 0)) {
result++;
preDiff = curDiff;
}
}
return result;
}
public static void main(String[] args) {
int[] nums = {1, 17, 5, 10, 13, 15, 10, 5, 16, 8};
System.out.println(wiggleMaxLength(nums));
}
}
4.最大子序和:代码随想录
力扣链接:. - 力扣(LeetCode)
贪心的应用就在于多吃几个元素,直到吃掉当前元素后,局部和小于等于0了,从下一个位置开始继续找最大的子序和。
/**
* 最大子序和
*
* https://leetcode.cn/problems/maximum-subarray/
*/
public class _27_3MaxSuborderSum {
public static int maxSubArray(int[] nums) {
if (nums.length == 1){
return nums[0];
}
int result = Integer.MIN_VALUE; //全局最优解
int count = 0; //局部最优解
for (int i = 0;i<nums.length;i++){
count+=nums[i];
result = Math.max(result, count); //比较两个最优解的大小
if (count<=0){
count=0; //如果此时已经小于0了,那么就没必要将这个继续加了,从下一个重新加
}
}
return result;
}
public static void main(String[] args) {
int[] nums = {-2,1,-3,4,-1,2,1,-5,4};
System.out.println(maxSubArray(nums));
}
}
上面的题还有动态规划的版本,个人看不懂,上学时候数学推导都不太会别说用代码写了。加油吧,这次不管咋都得试试。