主要思想:
- 由局部最优推导全局最优,并且举不出明显的反例
- 需要自己思考,没有必要进行数学证明。
1、饼干分发
优先用大饼喂大胃
// 思路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--) {
//保证别报错
// g[index] <= s[start] 大饼干优先满足大胃口。
if(start >= 0 && g[index] <= s[start]) {
start--;
count++;
}
}
return count;
}
小饼干优先满足小胃口
2、最长子序列
本题中的局部思想,是通过简单求和,如果和大于result,则对result进行赋值,否则将局部和赋值为0,类似与左右值的变化
class Solution {
public int maxSubArray(int[] nums) {
if (nums.length == 1){
return nums[0];
}
int result = Integer.MIN_VALUE;//记录min值,用于做比较
int count = 0;
for (int i = 0; i < nums.length; i++) {
count = count + nums[i]; //局部和
if (count > result) {
result = count; //将最终结果和局部和进行比较
}
if (count <= 0) {
count = 0; //索引下标不变,变得是总和,其实也想到与改变下标
}
}
return result;
}
}
3、股票最大值
主要思想参考上题,赋值两个变量,分别记录局部最优和全局最优,在局部最优逻辑中,用两天的值进行比较
public int maxProfit(int[] prices) {
if (prices.length == 0) {
return 0;
}
int sum = 0; //综合
int count = 0; //局部和
for (int i = 1; i < prices.length; i++) {
if (prices[i - 1] > prices[i]) {
count = 0;
} else {
count += (prices[i] - prices[i - 1]);
}
sum += count;
}
return sum;
}
优化版
public int maxProfit(int[] prices) {
int result = 0;
for (int i = 1; i < prices.length; i++) {
result += Math.max(prices[i] - prices[i - 1], 0);
}
return result;
}
4、跳跃游戏
从第一步开始跳,当前位置能到的最远距离:nums[i] + i ,再用converge = Math.max(converge, nums[i] + i) 与目标位置进行判断,如果能到达则返回true
class Solution {
public boolean canJump(int[] nums) {
if (nums.length==1) return true;
int converge = 0;
for (int i = 0; i <= converge; i++) { //设定范围,第一步可以直接走
converge = Math.max(converge, nums[i] + i); //后续取步数最大值
if (converge >= nums.length - 1) {
return true;
}
}
return false;
}
}
5、K 次取反后最大化的数组和
思路: 对于数组中的值有三种情况
- 全是正数:选择较小的数字或者多次反转
- 全是负数:选择