区间调度
跳跃游戏
- leedcode-55
- 问题描述:给定一个非负整数数组,最初位于数组的第一个位置,数组中的每个元素代表你在该位置可以跳跃的最长长度,判断是否能够到达最后一个位置
思路1
- 从后往前遍历
public boolean canJump(int[] nums) {
int last = nums.length-1;
for(int i=nums.length-2; i>=0; i--) {
if(nums[i]+i >= last) {
last = i;
}
}
return last == 0;
}
思路2
- 从前往后遍历
// error [0] [2, 0, 0]
public boolean canJump(int[] nums) {
int n = nums.length;
int farthest = 0;
for (int i = 0; i < n - 1; i++) {
// 不断计算能跳到的最远距离
farthest = max(farthest, i + nums[i]);
// 可能碰到了 0,卡住跳不动了
if (farthest <= i)
return false;
}
return farthest >= n - 1;
}
public boolean canJump(int[] nums) {
int maxIdx = 0;
for(int i = 0; i < nums.length; i++){
if(i <= maxIdx){
maxIdx = Math.max(maxIdx, nums[i] + i);
}
}
return maxIdx >= nums.length - 1;
}
- leedcode-45
- 问题描述:给定一个非负整数数组,最初位于数组的第一个位置,数组中的每个元素代表你在该位置可以跳跃的最大长度,你的目标是使用最少的跳跃次数到达数组的最后一个位置(假设总可以到达)
动态规划:
- dp[i]:表示当前位置到终点最少次数(从后往前填充)
- 思想:从倒数第二个位置开始,dp[i] = [i…Math.min(i + nums[i], n - 1)] 区间的最小值 + 1
贪心算法
public int jump1(int[] nums) {
// 记录当前步数内可以走的最远位置
int end = 0;
// 步数
int jump = 0;
// 当前位置所能跳到的最远距离
int farthest = 0;
for(int i = 0; i < nums.length - 1; i++) {
farthest = Math.max(farthest, nums[i] + i);
if(i == end) {
jump++;
end = farthest;
if(end == nums.length - 1) {
return jump;
}
}
}
return jump;
}
纸牌均分