follow:代码随想录
55 跳跃游戏
题目描述:
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标
解析:
方法一:暴力求解
从最后一个位置向前看:能到达该位置的下标有哪些,并把它们加入到队列中,如果0能到达该位置,则结束。
public boolean canJump(int[] nums) {
if(nums.length <= 1) return true;
//队列维护要遍历的下标
Deque<Integer> queue = new LinkedList<>();
//标志子问题是否已经被计算过
boolean[] flag = new boolean[nums.length];
queue.addLast(nums.length - 1);
while(!queue.isEmpty()){
int index = queue.removeFirst();
//判断该位置可以从哪些位置到达
for(int i = 0; i < index; i++){
if(nums[i] >= (index - i) && !flag[i]){
//如果0下标能到达,则结束
if(i == 0) return true;
queue.addLast(i);
flag[i] = true;
}
}
}
return false;
}
方法二:
贪心算法:每次都取最大跳跃值,可得到最大跳跃覆盖范围,最终能否覆盖到终点。
public boolean canJump(int[] nums) {
//end表示当前的覆盖范围
int end = 0;
for(int i = 0; i <= end; i++){
//扩大覆盖范围
end = Math.max(end, i + nums[i]);
//覆盖范围是否到达终点
if(end >= nums.length - 1) return true;
}
return false;
}
45. 跳跃游戏2⃣️
题目描述:
给你一个非负整数数组 nums ,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。
解析:
方法一:动态规划
- dp数组及其含义
dp[i]表示从初始点最少走多少步能到达下标为i的位置 - 确定递推公式
从0到i-1,依次看到达i点的步数哪个最小
dp[i] = Math.min(dp[i], dp[j] + 1); - 初始化
在起点看,走0步到达第一个位置,dp[0]=0
其他位置都是最大值
public int jump(int[] nums) {
//dp表示从初始点最少走多少步能到达该点
int[] dp = new int[nums.length];
Arrays.fill(dp, Integer.MAX_VALUE);
//初始化:在起点看,走0步
dp[0] = 0;
for(int i = 1; i < nums.length; i++){
for(int j = 0; j < i; j++){
if(nums[j] >= (i - j)){
dp[i] = Math.min(dp[i], dp[j] + 1);
}
}
}
return dp[nums.length - 1];
}
方法二:贪心算法
依然是看最大覆盖范围,但是本题要求最小步数,所以要看最小步数所能覆盖的最大范围。
- 什么时候增加步数
当遍历到当前最大覆盖范围时,步数加一,并更新最大覆盖范围。意思是:当前最小步数,所能达到的最远距离
- 什么时候结束
遍历到某个位置,最远覆盖范围覆盖了最后一个位置
public int jump(int[] nums) {
if(nums.length == 1) return 0;
int result = 0;
int curdis = 0;
int fardis = 0;
for(int i = 0; i < nums.length; i++){
fardis = Math.max(fardis, i + nums[i]);
//已经覆盖了最后一个位置
if(fardis >= nums.length - 1){
return result + 1;
}
//当前最小步数已经到了最远距离
if(i == curdis){
result++;
curdis = fardis;
}
}
return result;
}
买卖骨片的最佳时机2⃣️
题目描述:
给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。
在每一天,你可能会决定购买和/或出售股票。
你在任何时候 最多 只能持有 一股 股票。
你也可以购买它,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
解析:
本题可以用动态规划,也可以用贪心算法
贪心思想:只要第二天的价格比第一天的价格高就卖出去
public int maxProfit(int[] prices) {
int result = 0;
for(int i = 1; i < prices.length; i++){
if(prices[i] > prices[i - 1]){
result += prices[i] - prices[i - 1];
}
}
return result;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)