代码随想录算法训练营第四十九天| 121. 买卖股票的最佳时机 122.买卖股票的最佳时机II
一、力扣121. 买卖股票的最佳时机
题目链接:
思路:买卖股票的最佳时机,只进行一次买入和一次卖出行为。贪心的思想是找到当前最低的价位,在最高时卖出,那就可以设置一个初始值为最大值,然后向后遍历,一边遍历,一边记录当前最小值,然后用num[i]减去最小值,来进行比较。
贪心解法
class Solution {
public int maxProfit(int[] prices) {
int min = Integer.MAX_VALUE;
int sum = 0;
for (int i = 0; i < prices.length; i++) {
min = Math.min(min, prices[i]);
sum = Math.max(sum, prices[i]-min);
}
return sum;
}
}
动态规划解法
确定dp数组,设置dp[i][0]为当前持有股票时,手中的现金数。dp[i][1]为当前不持有股票时,手中的现金数。
确定递推公式,持有时,dp[i][0]=max(dp[i-1][0], -nums[i]) ,持有分为之前持有和今天持有,之前持有了即为dp[i-1][0],如果是今天刚持有,之前现金是0,所以是-nums[i]
不持有时,dp[i][1]=max(dp[i-1][1], dp[i-1][0]+nums[i]),不持有分为之前不持有和今天刚不持有,之前不持有即为上一天不持有的值,今天刚不持有,说明昨天是持有的,即 dp[i-1][0]+nums[i]
确定初始化,dp[0][0]=-nums[0],dp[0][1]=0。
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
int[][] dp = new int[len][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < len; i++) {
dp[i][0] = Math.max(dp[i-1][0], -prices[i]);
dp[i][1] = Math.max(dp[i-1][1], prices[i] + dp[i-1][0]);
}
return Math.max(dp[len-1][0], dp[len-1][1]);
}
}
二、力扣122.买卖股票的最佳时机II
题目链接:
思路:类似于1,2,3,最大为3-1,等价于2-1,3-2。贪心只收集相邻差值为正数的结果。
贪心:
class Solution {
public int maxProfit(int[] prices) {
int count = 0;
for (int i = 1; i < prices.length; i++) {
count += Math.max(prices[i] - prices[i-1], 0);
}
return count;
}
}
动态规划:和上面类似,只不过,当天买入,前一天一定是卖出的,故手中金额为dp[i-1][1] - prices[i]
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
int[][] dp = new int[len][2];
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i = 1; i < len; i++) {
dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] - prices[i]);
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] + prices[i]);
}
return Math.max(dp[len-1][0], dp[len-1][1]);
}
}