贪心算法
122.买卖股票的最佳时机II
贪心法:
只要股票价格上涨就卖出
- 当出现1->5->4->6: 此时最大收益为5-1+6-4=6
- 要是一直上涨: 1->3->5->6这种呢, 你在3,5,6将其卖出是等价于你在1买入, 在6卖出的
- 即 3-1+5-3+6-5 == 6-1 = 5
代码:
class Solution {
public int maxProfit(int[] prices) {
int ans = 0;
for(int i=0; i<prices.length-1; i++){
if(prices[i] < prices[i+1]) {
ans+= prices[i+1]-prices[i];
}
}
return ans;
}
}
55.跳跃游戏
贪心:
标记法
- 用一个标记是否可达数组is_reach, 若数组下标i为true, 代表当前位置可达, 若为false, 则代表当前位置不可达
- 遍历数组, 若当前位置不可达, 则代表其以后位置也永远不可达, 直接返回false
- 若当前位置可达, 则代表将其能达到的位置全部标记为true-可达
代码:
class Solution {
public boolean canJump(int[] nums) {
boolean[] is_reach = new boolean[nums.length];
// 初始化第一个位置是可到达的
is_reach[0] = true;
for(int i=0; i<nums.length; i++){
// 若当前位置可到达, 则更新其能到达的位置
if(is_reach[i]) {
int j = i;
while(j <= i + nums[i] && j < nums.length){
is_reach[j] = true;
j++;
}
}else return false;
}
return true;
}
}
45.跳跃游戏II
覆盖法:
- 用start 和 end 代表当前可达区间的起点和终点
- 若该区间达不到终点, 则代表至少需要跳出下一步
- 下一步的起点就是上一步的终点, 同时遍历当前区间, 找到当前步能达到的最远位置即下一步的终点
代码:
class Solution {
// 跳跃游戏I求的是是否能达到最后一个元素
// 跳跃游戏II求的是到达最后一个元素的最小跳跃次数
// 跳到任意的nums[i+j]处 --- 覆盖法
public int jump(int[] nums) {
if(nums.length < 2) return 0;
// 贪心法: 判断跳到下一步的最大覆盖范围
int n = nums.length;
// 左闭右开区间, 取得到最左边, 取不到最右边
int start = 0, end = 1, ans = 0;
// 当前这一步不能到达终点, 那他必须要跳出下一步
while(end < n) {
// 找到当前区间能跳到的最远位置
int maxPos = 0;
for(int i=start; i < end; i++){
maxPos = Math.max(maxPos, i + nums[i]);
}
// 下一跳起跳范围开始的位置
start = end;
// 下一跳起跳范围结束的位置
end = maxPos + 1;
ans++;
}
return ans;
}
}