代码随想录第四十九天|121、122
Leetcode : 121. 买卖股票的最佳时机
题目链接: 买卖股票的最佳时机
自己的思路:只能想到两层for循环暴力搜索,但是超时!!!
正确思路:动态规划!这里如果只考虑一维dp数组是没办法考虑清楚具体的情况的,比如dp[i]表示第i天所产生的最大利润,但是这样的话第i天以后的dp数组就没办法进行表示了!所以考虑使用二维dp数组;动规五部曲:1、dp数组的含义:dp[i][0]表示第i天持有这个股票所产生的最大利润,dp[i][1]表示不持有这个股票所产生的最大利润,注意我们这里持有这个股票不代表第i天买入的,也可能之前就买入了,我们这里不持有这个股票也不代表第i天卖出,也可能之前就卖出了;2、递推公式:假设一开始最大利润是0,当天的股票买卖的最大利润一定和前一天有关,假设当天持有这个股票:(1)、之前就持有dp[i-1][0](2)、第i天才持有-prices[i];假设当天不持有这个股票:(1)、之前就不持有这个股票dp[i-1][1](2)、第i天才不持有这个股票dp[i-1][0]+prices[i];3、dp数组初始化:由于后面的数都是由第1天算出来的,所以初始化dp[0][0]=-prices[0](当天买入);dp[0][1]=0(当天不买入);4、遍历顺序:因为要求最后一天的,需要从前向后递推;5、打印dp数组:主要用于debug!!!!
代码:
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
//dp数组的初始化
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i=1;i<prices.length;i++){
//递推公式
dp[i][0] = Math.max(dp[i-1][0],-prices[i]);
dp[i][1] = Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);
}
return Math.max(dp[prices.length-1][0],dp[prices.length-1][1]);
}
}
Leetcode :122. 买卖股票的最佳时机 II
题目链接: 买卖股票的最佳时机 II
自己的思路:贪心;找累计利润最大的时候就是我们能得到的最大利润!!!!
代码:
class Solution {
public int maxProfit(int[] prices) {
int res = 0;
for (int i=1;i<prices.length;i++){
if (prices[i]-prices[i-1]>0){
//贪心
//只要两天差值为正的股票
//累计利润
res+=prices[i]-prices[i-1];
}
}
return res;
}
}
动态规划思路:和上一道题基本类似,只需要更改一处代码,就是在计算当前持有股票的时候,当时的最大金额是dp[i-1][1],然后如果买入这个股票的话,就要减去prices[i]!
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][2];
//dp数组初始化
dp[0][0] = -prices[0];
dp[0][1] = 0;
for (int i =1;i<prices.length;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[prices.length-1][0],dp[prices.length-1][1]);
}
}