买卖股票的最佳时机 LeetCode 121
题目链接:[LeetCode 121 - 简单]
思路
该题只能有一次买进和卖出的机会。 因此可以直接将dp数组转化为一个变量。
动态规划:
class Solution {
public int maxProfit(int[] prices) {
int[] dp = new int[prices.length];
int min = prices[0];
for(int i=1;i<prices.length;i++){
if(prices[i]>min){
dp[i]=Math.max(prices[i]-min,dp[i-1]);
}else{
dp[i]=dp[i-1];
}
min=Math.min(prices[i],min);
}
return dp[prices.length-1];
}
}
优化后
class Solution {
public int maxProfit(int[] prices) {
int min = Integer.MAX_VALUE;
int res = 0;
for(int price:prices){
res=Math.max(res,price-min);
min=Math.min(min,price);
}
return res;
}
}
买卖股票的最佳时机 II LeetCode 122
题目链接:[LeetCode 122 - 中等]
思路
发现之前在贪心中做过该题 使用动态规划又是不同的思路
动态规划:
一维数组
class Solution {
public int maxProfit(int[] prices) {
int[] dp = new int[prices.length];
int min = prices[0];
for(int i=1;i<prices.length;i++){
if(prices[i]>min){
dp[i]=dp[i-1]+prices[i]-min;
min=prices[i];
}else{
dp[i]=dp[i-1];
min=Math.min(min,prices[i]);
}
}
return dp[prices.length-1];
}
}
一个变量
class Solution {
public int maxProfit(int[] prices) {
int res = 0;
int min = prices[0];
for(int i=1;i<prices.length;i++){
if(prices[i]>min){
res+=prices[i]-min;
min=prices[i];
}else{
min=Math.min(min,prices[i]);
}
}
return res;
}
}
另一种优化思路
class Solution {
public int maxProfit(int[] prices) {
int[] dp = new int[2];
//0持有 1卖出
dp[0]=-prices[0];
dp[1]=0;
for(int i=1;i<prices.length;i++){
dp[0]=Math.max(dp[0],dp[1]-prices[i]);
dp[1]=Math.max(dp[1],dp[0]+prices[i]);
}
return dp[1];
}
}
贪心:
class Solution {
public int maxProfit(int[] prices) {
int result = 0;
for(int i=0;i<prices.length-1;i++){
if(prices[i]<prices[i+1]){
result += prices[i+1] - prices[i];
}
}
return result;
}
}
买卖股票的最佳时机 III LeetCode 123
题目链接:[LeetCode 123 - 困难]
思路
定义了五种状态。
动态规划:
class Solution {
public int maxProfit(int[] prices) {
if(prices.length==1)return 0;
int[][] dp = new int[prices.length][5];
//定义五种状态,0:没有操作 1:第一次买入 2:第一次卖出3:第二次买入4:第二次卖出
dp[0][1]=-prices[0];
dp[0][3]=-prices[0];
for(int i=1;i<prices.length;i++){
dp[i][1]=Math.max(dp[i-1][1],-prices[i]);
dp[i][2]=Math.max(dp[i-1][2],dp[i-1][1]+prices[i]);
dp[i][3]=Math.max(dp[i-1][3],dp[i][2]-prices[i]);
dp[i][4]=Math.max(dp[i-1][4],dp[i][3]+prices[i]);
}
return dp[prices.length-1][4];
}
}
class Solution {
public int maxProfit(int[] prices) {
if(prices.length==1)return 0;
int[] dp = new int[5];
//定义五种状态,0:没有操作 1:第一次买入 2:第一次卖出3:第二次买入4:第二次卖出
dp[1]=-prices[0];
dp[3]=-prices[0];
for(int i=1;i<prices.length;i++){
dp[1]=Math.max(dp[1],-prices[i]);
dp[2]=Math.max(dp[2],dp[1]+prices[i]);
dp[3]=Math.max(dp[3],dp[2]-prices[i]);
dp[4]=Math.max(dp[4],dp[3]+prices[i]);
}
return dp[4];
}
}
买卖股票的最佳时机 IV LeetCode 188
题目链接:[LeetCode 188 - 困难]
思路
与#123思路一致,但是代码稍有不同。
动态规划:
class Solution {
public int maxProfit(int k, int[] prices) {
int[] dp = new int[k*2+1];
for(int j=0;j<k;j++){
dp[j*2+1]=-prices[0];
}
for(int i=0;i<prices.length;i++){
dp[1]=Math.max(dp[1],-prices[i]);
dp[2]=Math.max(dp[2],dp[1]+prices[i]);
for(int j=1;j<k;j++){
dp[2*j+1]=Math.max(dp[2*j+1],dp[2*j]-prices[i]);
dp[2*j+2]=Math.max(dp[2*j+2],dp[2*j+1]+prices[i]);
}
}
return dp[2*k];
}
}
买卖股票的最佳时机含冷冻期 LeetCode 309
题目链接:[LeetCode 309 - 中等]
思路
主要为冷静期期间不能购买股票,因此需要在不持有收益时卖出。
动态规划:
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length+1][2];
//0:第i天持有股票收益 1:第i天不持有股票收益
dp[1][0]=-prices[0];
for(int i=2;i<=prices.length;i++){
dp[i][0]=Math.max(dp[i-1][0],dp[i-2][1]-prices[i-1]);
dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]+prices[i-1]);
}
return dp[prices.length][1];
}
}
买卖股票的最佳时机 LeetCode 714
题目链接:[LeetCode 714 - 中等]
思路
动态规划:
class Solution {
public int maxProfit(int[] prices, int fee) {
int[] dp = new int[2];
dp[0]=-prices[0];
for(int i=1;i<prices.length;i++){
dp[0]=Math.max(dp[1]-prices[i],dp[0]);
dp[1]=Math.max(dp[0]+prices[i]-fee,dp[1]);
}
return dp[1];
}
}