贪心算法
贪心算法一般分为如下四步:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
做贪心类的题目 很难去按照这四步去思考
做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。
分发饼干
力扣连接:455. 分发饼干(简单)
1.贪心的方法
局部最优就是小饼干喂给胃口小的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。
关键点:
- 可以尝试使用贪心策略,先将饼干数组和小孩数组排序。
- 小饼干先喂饱小胃口
代码
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int left = 0;
int right = 0;
int result = 0;
while(left<g.length && right<s.length){
if(g[left]>s[right]){
right++;
}else{
left++;
right++;
result++;
}
}
return result;
}
}
摆动序列
力扣连接:376. 摆动序列(中等)
1.递归的方法
由于是二叉搜索树,所以只要遍历二叉搜索树,找到空节点 插入元素就可以了,那么这道题其实就简单了。
图解步骤
情况一:上下坡中有平坡
情况二:数组首尾两端
情况三:单调坡度有平坡
关键点:
本题要考虑三种情况:
- 情况一:上下坡中有平坡
- 情况二:数组首尾两端
- 情况三:单调坡中有平坡
递归代码
class Solution {
public int wiggleMaxLength(int[] nums) {
int curDiff = 0; // 当前一对差值
int preDiff = 0; // 前一对差值
int result = 1; // 记录峰值个数,序列默认序列最右边有一个峰值
for(int i=0;i<nums.length-1;i++){
curDiff = nums[i+1] - nums[i];
// 出现峰值
if((curDiff>0 && preDiff<=0) || (curDiff<0 && preDiff>=0)){
result++;
preDiff = curDiff; // 注意这里,只在摆动变化的时候更新prediff
}
}
return result;
}
}
最大子数组和
力扣连接:53. 最大子数组和(中等)
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
图解步骤
关键点:
- 只要连续和为正数我们就保留。
代码
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length==1) return nums[0];
int sum = 0;
int max = Integer.MIN_VALUE;
int index = 0;
while(index<nums.length){
sum += nums[index];
max = Math.max(sum, max);
if(sum<0){
sum = 0;
}
index++;
}
return max;
}
}