一个人的朝圣 — LeetCode打卡第32天
知识总结
今天的做的题目都比较有意思, 思路很巧妙
Leetcode 122. 买卖股票的最佳时机 II
题目说明
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
代码说明
自己做的想法:
最优策略, 如果股票明天在涨, 继续保持。如果第二天下跌,则出手。 然后更新买的价格。 如果一直跌, 则更新buyPrice确保其为最低。最后一天时直接卖出, 将profit增进total 中。
class Solution {
public int maxProfit(int[] prices) {
if(prices.length <= 1) return 0;
int buyPrice = prices[0];
int profit = 0;
int total = 0;
for(int i = 1; i < prices.length; i++){
if(prices[i] > prices[i-1]){
profit = prices[i] - buyPrice;
}else{
total +=profit;
profit =0;
buyPrice = prices[i];
}
if(i == prices.length -1){
total += profit;
break;
}
}
return total;
}
}
然后问题可以简化成, 算出所有增长的涨幅总和。
public class Solution {
public int maxProfit(int[] prices) {
int res = 0;
for(int i = 1; i< prices.length; i++){
if(prices[i] > prices[i-1]){
res+= prices[i] - prices[i-1];
}
}
return res;
}
}
Leetcode 跳跃游戏
题目说明
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
代码说明
curMax 表示可以当前可以跳的最远距离
class Solution {
public boolean canJump(int[] nums) {
if(nums.length <= 1) return true;
int curMax = 0;
for(int i = 0; i< nums.length; i++){
if(i > curMax){
return false;
}
curMax = Math.max(curMax, nums[i] + i);
}
return true;
}
}
Leetcode 45. 跳跃游戏 II
题目说明
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。
每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:
0 <= j <= nums[i]
i + j < n
返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]。
代码说明
自己写的比较复杂, 从终点往前推, 看走到终点需要多少步。maxValue - 1000 是为了避免越界从正数变成负数。
class Solution {
public int jump(int[] nums) {
int l = nums.length;
if(l <= 1) return 0;
int[] dp = new int[l];
for(int i = l -2; i>=0; i--){
int minStep = Integer.MAX_VALUE - 1000;
if(i + nums[i] >= l -1){
dp[i] = 1;
continue;
}
if(nums[i] == 0){
dp[i] = Integer.MAX_VALUE - 1000;
continue;
}
for(int j = nums[i] + i; j > i; j--){
minStep = Math.min(minStep, dp[j]);
}
dp[i] = minStep + 1;
}
return dp[0];
}
}
另外一种简单得多的方法, 并且别人还写了详细的注解
class Solution {
public int jump(int[] nums) {
// 记录当前能跳跃到的位置的边界下标
int border = 0;
// 记录在边界范围内,能跳跃的最远位置的下标
int maxPosition = 0;
// 记录所用步数
int steps = 0;
for(int i=0;i<nums.length-1;i++){
// 继续往下遍历,统计边界范围内,哪一格能跳得更远,每走一步就更新一次能跳跃的最远位置下标
// 其实就是在统计下一步的最优情况
maxPosition = Math.max(maxPosition,nums[i]+i);
// 如果到达了边界,那么一定要跳了,下一跳的边界下标就是之前统计的最优情况maxPosition,并且步数加1
if(i==border){
border = maxPosition;
steps++;
}
}
return steps;
}
}