diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index 45b61666..486e08bd 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -194,7 +194,7 @@ public: ## 其他语言版本 -Java: +Java: > 贪心法: @@ -242,11 +242,12 @@ class Solution { class Solution { public int maxProfit(int[] prices) { int[] dp = new int[2]; + // 记录一次交易,一次交易有买入卖出两种状态 + // 0代表持有,1代表卖出 dp[0] = -prices[0]; dp[1] = 0; // 可以参考斐波那契问题的优化方式 - // dp[0] 和 dp[1], 其实是第 0 天的数据 - // 所以我们从 i=1 开始遍历数组,一共有 prices.length 天, + // 我们从 i=1 开始遍历数组,一共有 prices.length 天, // 所以是 i<=prices.length for (int i = 1; i <= prices.length; i++) { // 前一天持有;或当天买入 @@ -263,7 +264,7 @@ class Solution { } ``` -Python: +Python: > 贪心法: ```python @@ -307,7 +308,8 @@ class Solution: return dp[(length-1) % 2][1] ``` -Go: +Go: + ```Go func maxProfit(prices []int) int { length:=len(prices) @@ -334,7 +336,7 @@ func max(a,b int)int { } ``` -JavaScript: +JavaScript: > 动态规划 diff --git a/problems/0122.买卖股票的最佳时机II.md b/problems/0122.买卖股票的最佳时机II.md index 5b117563..f6d5906a 100644 --- a/problems/0122.买卖股票的最佳时机II.md +++ b/problems/0122.买卖股票的最佳时机II.md @@ -131,7 +131,7 @@ public: ## 其他语言版本 -### Java +Java: ```java // 贪心思路 @@ -167,28 +167,8 @@ class Solution { // 动态规划 } ``` -```java -// 优化空间 -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-1]); - // 前一天卖出; 或当天卖出,当天卖出,得先持有 - dp[1]=Math.max(dp[1], dp[0]+prices[i-1]); - } - return dp[1]; - } -} -``` +Python: - - -### Python ```python class Solution: def maxProfit(self, prices: List[int]) -> int: @@ -212,7 +192,8 @@ class Solution: return dp[-1][1] ``` -### Go +Go: + ```golang //贪心算法 func maxProfit(prices []int) int { @@ -248,7 +229,8 @@ func maxProfit(prices []int) int { } ``` -### Javascript +Javascript: + 贪心 ```Javascript var maxProfit = function(prices) { @@ -284,7 +266,8 @@ const maxProfit = (prices) => { }; ``` -### C +C: + ```c int maxProfit(int* prices, int pricesSize){ int result = 0; diff --git a/problems/0122.买卖股票的最佳时机II(动态规划).md b/problems/0122.买卖股票的最佳时机II(动态规划).md index e701a821..8f03e88e 100644 --- a/problems/0122.买卖股票的最佳时机II(动态规划).md +++ b/problems/0122.买卖股票的最佳时机II(动态规划).md @@ -147,25 +147,30 @@ class Solution } return dp[n - 1][0]; // 卖出股票收益高于持有股票收益,因此取[0] } +} +``` - // 实现2:变量存储 - // 第一种方法需要用二维数组存储,有空间开销,其实关心的仅仅是前一天的状态,不关注更多的历史信息 - // 因此,可以仅保存前一天的信息存入 dp0、dp1 这 2 个变量即可 - // 时间复杂度:O(n),空间复杂度O(1) +```java +// 优化空间 +class Solution { public int maxProfit(int[] prices) { - int n = prices.length; - int dp0 = 0, dp1 = -prices[0]; // 定义变量,存储初始状态 - for (int i = 1; i < n; ++i) { - int newDp0 = Math.max(dp0, dp1 + prices[i]); // 第 i 天,没有股票 - int newDp1 = Math.max(dp1, dp0 - prices[i]); // 第 i 天,持有股票 - dp0 = newDp0; - dp1 = newDp1; + 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-1]); + // 前一天卖出; 或当天卖出,当天卖出,得先持有 + dp[1] = Math.max(dp[1], dp[0] + prices[i-1]); } - return dp0; + return dp[1]; } } ``` + + Python: > 版本一: diff --git a/problems/0123.买卖股票的最佳时机III.md b/problems/0123.买卖股票的最佳时机III.md index db3f0278..8fa3a8e0 100644 --- a/problems/0123.买卖股票的最佳时机III.md +++ b/problems/0123.买卖股票的最佳时机III.md @@ -188,7 +188,7 @@ dp[1] = max(dp[1], dp[0] - prices[i]); 如果dp[1]取dp[1],即保持买入股 ## 其他语言版本 -### Java +Java: ```java // 版本一 @@ -221,30 +221,30 @@ class Solution { // 版本二: 空间优化 class Solution { public int maxProfit(int[] prices) { - int[] dp=new int[4]; - // 存储两天的状态就行了 - // dp[0]代表第一次买入 - dp[0]=-prices[0]; - // dp[1]代表第一次卖出 - dp[1]=0; - // dp[2]代表第二次买入 - dp[2]=-prices[0]; - // dp[3]代表第二次卖出 - dp[3]=0; - for(int i=1; i<=prices.length; i++){ + int[] dp = new int[4]; + // 存储两次交易的状态就行了 + // dp[0]代表第一次交易的买入 + dp[0] = -prices[0]; + // dp[1]代表第一次交易的卖出 + dp[1] = 0; + // dp[2]代表第二次交易的买入 + dp[2] = -prices[0]; + // dp[3]代表第二次交易的卖出 + dp[3] = 0; + for(int i = 1; i <= prices.length; i++){ // 要么保持不变,要么没有就买,有了就卖 - dp[0]=Math.max(dp[0], -prices[i-1]); - dp[1]=Math.max(dp[1], dp[0]+prices[i-1]); - // 这已经是第二天了,所以得加上前一天卖出去的价格 - dp[2]=Math.max(dp[2], dp[1]-prices[i-1]); - dp[3]=Math.max(dp[3], dp[2]+prices[i-1]); + dp[0] = Math.max(dp[0], -prices[i-1]); + dp[1] = Math.max(dp[1], dp[0]+prices[i-1]); + // 这已经是第二次交易了,所以得加上前一次交易卖出去的收获 + dp[2] = Math.max(dp[2], dp[1]-prices[i-1]); + dp[3] = Math.max(dp[3], dp[2]+ prices[i-1]); } return dp[3]; } } ``` -### Python +Python: > 版本一: ```python @@ -311,9 +311,7 @@ func max(a,b int)int{ } ``` - - -### JavaScript +JavaScript: > 版本一: @@ -352,7 +350,7 @@ const maxProfit = prices => { }; ``` -### Go +Go: > 版本一: ```go diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md index 0e898b43..615ebd5c 100644 --- a/problems/0188.买卖股票的最佳时机IV.md +++ b/problems/0188.买卖股票的最佳时机IV.md @@ -165,7 +165,7 @@ public: ## 其他语言版本 -Java: +Java: ```java // 版本一: 三维 dp数组 @@ -228,9 +228,9 @@ class Solution { if(k == 0){ return 0; } - // 其实就是123题的扩展,123题只用记录2天的状态 - // 这里记录k天的状态就行了 - // 每天都有买入,卖出两个状态,所以要乘 2 + // 其实就是123题的扩展,123题只用记录2次交易的状态 + // 这里记录k次交易的状态就行了 + // 每次交易都有买入,卖出两个状态,所以要乘 2 int[] dp = new int[2 * k]; // 按123题解题格式那样,做一个初始化 for(int i = 0; i < dp.length / 2; i++){ @@ -246,15 +246,16 @@ class Solution { dp[j + 1] = Math.max(dp[j + 1], dp[j] + prices[i - 1]); } } - // 返回最后一天卖出状态的结果就行了 + // 返回最后一次交易卖出状态的结果就行了 return dp[dp.length - 1]; } } ``` +Python: -Python: 版本一 + ```python class Solution: def maxProfit(self, k: int, prices: List[int]) -> int: @@ -285,8 +286,10 @@ class Solution: dp[j] = max(dp[j],dp[j-1]+prices[i]) return dp[2*k] ``` -Go: +Go: + 版本一: + ```go // 买卖股票的最佳时机IV 动态规划 // 时间复杂度O(kn) 空间复杂度O(kn) @@ -356,10 +359,7 @@ func max(a,b int)int{ } ``` - - - -Javascript: +Javascript: ```javascript // 方法一:动态规划 diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md index 8520e655..48106bd8 100644 --- a/problems/0309.最佳买卖股票时机含冷冻期.md +++ b/problems/0309.最佳买卖股票时机含冷冻期.md @@ -185,6 +185,28 @@ class Solution { } ``` +```java +// 一维数组优化 +class Solution { + public int maxProfit(int[] prices) { + int[] dp=new int[4]; + + dp[0] = -prices[0]; + dp[1] = 0; + for(int i = 1; i <= prices.length; i++){ + // 使用临时变量来保存dp[0], dp[2] + // 因为马上dp[0]和dp[2]的数据都会变 + int temp = dp[0]; + int temp1 = dp[2]; + dp[0] = Math.max(dp[0], Math.max(dp[3], dp[1]) - prices[i-1]); + dp[1] = Math.max(dp[1], dp[3]); + dp[2] = temp + prices[i-1]; + dp[3] = temp1; + } + return Math.max(dp[3],Math.max(dp[1],dp[2])); + } +} +``` Python: diff --git a/problems/0714.买卖股票的最佳时机含手续费.md b/problems/0714.买卖股票的最佳时机含手续费.md index afa2e2f6..f7ddeaf7 100644 --- a/problems/0714.买卖股票的最佳时机含手续费.md +++ b/problems/0714.买卖股票的最佳时机含手续费.md @@ -196,7 +196,9 @@ class Solution { // 动态规划 ``` + Python: + ```python class Solution: # 贪心思路 def maxProfit(self, prices: List[int], fee: int) -> int: diff --git a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md index 2b3416d4..700b8cde 100644 --- a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md +++ b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md @@ -134,6 +134,20 @@ public int maxProfit(int[] prices, int fee) { } return Math.max(dp[len - 1][0], dp[len - 1][1]); } + +// 一维数组优化 +class Solution { + public int maxProfit(int[] prices, int fee) { + int[] dp = new int[2]; + 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 - 1]); + dp[1] = Math.max(dp[1], dp[0] + prices[i - 1] - fee); + } + return dp[1]; + } +} ``` Python: