diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md
index def69277..0b1622ac 100644
--- a/problems/0188.买卖股票的最佳时机IV.md
+++ b/problems/0188.买卖股票的最佳时机IV.md
@@ -404,6 +404,47 @@ func max188(a, b int) int {
}
```
+版本三:空间优化版本
+
+```go
+func maxProfit(k int, prices []int) int {
+ n := len(prices)
+ // k次交易,2 * k种状态
+ // 状态从1开始计算,避免判断
+ // 奇数时持有(保持或买入)
+ // 偶数时不持有(保持或卖出)
+ dp := make([][]int, 2)
+ dp[0] = make([]int, k * 2 + 1)
+ dp[1] = make([]int, k * 2 + 1)
+
+ // 奇数状态时持有,i += 2
+ for i := 1; i <= k * 2; i += 2 {
+ dp[0][i] = -prices[0]
+ }
+
+ for i := 1; i < len(prices); i++ {
+ for j := 1; j <= k * 2; j++ {
+ if j % 2 == 1 {
+ dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - 1] - prices[i])
+ } else {
+ dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - 1] + prices[i])
+ }
+ }
+ }
+
+ return dp[(n - 1) % 2][k * 2]
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+
+
### JavaScript:
```javascript
@@ -558,3 +599,4 @@ impl Solution {
+
diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md
index 95689a48..4913b8bd 100644
--- a/problems/0309.最佳买卖股票时机含冷冻期.md
+++ b/problems/0309.最佳买卖股票时机含冷冻期.md
@@ -357,6 +357,42 @@ func max(a, b int) int {
}
```
+```go
+// 一维优化版本
+// 时间复杂度O(n), 空间复杂度O(1)
+func maxProfit(prices []int) int {
+
+ // 0: 持有,一直持有和买入
+ // 1: 不持有,一直不持有(不包含前一天卖出,因为这样的一天是冷静期,状态有区别)
+ // 2:不持有,今天卖出
+ // 3:冷静期,前一天卖出(一直不持有)
+ dp0, dp1, dp2, dp3 := -prices[0], 0, 0, 0
+
+ n := len(prices)
+
+ for i := 1; i < n; i++ {
+ t0 := max(dp0, max(dp1, dp3)-prices[i])
+ t1 := max(dp1, dp3)
+ t2 := dp0 + prices[i]
+ t3 := dp2
+
+ // 更新
+ dp0, dp1, dp2, dp3 = t0, t1, t2, t3
+ }
+
+ return max(dp1, max(dp2, dp3))
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+
+
### Javascript:
> 不同的状态定义 感觉更容易理解些
@@ -540,3 +576,4 @@ impl Solution {
+
diff --git a/problems/0503.下一个更大元素II.md b/problems/0503.下一个更大元素II.md
index 62066d85..5751bb91 100644
--- a/problems/0503.下一个更大元素II.md
+++ b/problems/0503.下一个更大元素II.md
@@ -168,6 +168,7 @@ class Solution {
```
### Python:
+> 版本一:
```python
class Solution:
@@ -181,6 +182,34 @@ class Solution:
stack.append(i%len(nums))
return dp
```
+
+> 版本二:针对版本一的优化
+
+```python3
+class Solution:
+ def nextGreaterElements(self, nums: List[int]) -> List[int]:
+ res = [-1] * len(nums)
+ stack = []
+ #第一次遍历nums
+ for i, num in enumerate(nums):
+ while stack and num > nums[stack[-1]]:
+ res[stack[-1]] = num
+ stack.pop()
+ stack.append(i)
+ #此时stack仍有剩余,有部分数‘无下一个更大元素’待修正
+ #第二次遍历nums
+ for num in nums:
+ #一旦stack为空,就表明所有数都有下一个更大元素,可以返回结果
+ if not stack:
+ return res
+ while stack and num > nums[stack[-1]]:
+ res[stack[-1]] = num
+ stack.pop()
+ #不要将已经有下一个更大元素的数加入栈,这样会重复赋值,只需对第一次遍历剩余的数再尝试寻找下一个更大元素即可
+ #最后仍有部分最大数无法有下一个更大元素,返回结果
+ return res
+```
+
### Go:
```go
@@ -203,7 +232,6 @@ func nextGreaterElements(nums []int) []int {
return result
}
```
-
### JavaScript:
```JS
diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md
index 6b9e5834..25d39486 100644
--- a/problems/0701.二叉搜索树中的插入操作.md
+++ b/problems/0701.二叉搜索树中的插入操作.md
@@ -283,32 +283,10 @@ class Solution:
return TreeNode(val)
self.traversal(root, val)
return root
-
```
递归法(版本二)
```python
-class Solution:
- def insertIntoBST(self, root, val):
- if root is None:
- return TreeNode(val)
- parent = None
- cur = root
- while cur:
- parent = cur
- if val < cur.val:
- cur = cur.left
- else:
- cur = cur.right
- if val < parent.val:
- parent.left = TreeNode(val)
- else:
- parent.right = TreeNode(val)
- return root
-```
-
-递归法(版本三)
-```python
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root is None or root.val == val:
@@ -326,7 +304,7 @@ class Solution:
return root
```
-递归法(版本四)
+递归法(版本三)
```python
class Solution:
def insertIntoBST(self, root, val):
@@ -340,10 +318,9 @@ class Solution:
root.right = self.insertIntoBST(root.right, val)
return root
-
```
-迭代法
+迭代法(版本一)
```python
class Solution:
def insertIntoBST(self, root, val):
@@ -366,10 +343,53 @@ class Solution:
else:
parent.right = node # 将新节点连接到父节点的右子树
- return root
-
-
+ return root
```
+
+迭代法(版本二)
+```python
+class Solution:
+ def insertIntoBST(self, root, val):
+ if root is None:
+ return TreeNode(val)
+ parent = None
+ cur = root
+ while cur:
+ parent = cur
+ if val < cur.val:
+ cur = cur.left
+ else:
+ cur = cur.right
+ if val < parent.val:
+ parent.left = TreeNode(val)
+ else:
+ parent.right = TreeNode(val)
+ return root
+```
+
+迭代法(精简)
+```python
+class Solution:
+ def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
+ if not root: # 如果根节点为空,创建新节点作为根节点并返回
+ return TreeNode(val)
+ cur = root
+ while cur:
+ if val < cur.val:
+ if not cur.left: # 如果此时父节点的左子树为空
+ cur.left = TreeNode(val) # 将新节点连接到父节点的左子树
+ return root
+ else:
+ cur = cur.left
+ elif val > cur.val:
+ if not cur.right: # 如果此时父节点的左子树为空
+ cur.right = TreeNode(val) # 将新节点连接到父节点的右子树
+ return root
+ else:
+ cur = cur.right
+
+```
+
-----
### Go
diff --git a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md
index 73714147..b0e8b141 100644
--- a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md
+++ b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md
@@ -188,6 +188,20 @@ class Solution:
return max(dp[-1][0], dp[-1][1])
```
+```python
+class Solution:
+ def maxProfit(self, prices: List[int], fee: int) -> int:
+ # 持有股票手上的最大現金
+ hold = -prices[0] - fee
+ # 不持有股票手上的最大現金
+ not_hold = 0
+ for price in prices[1:]:
+ new_hold = max(hold, not_hold - price - fee)
+ new_not_hold = max(not_hold, hold + price)
+ hold, not_hold = new_hold, new_not_hold
+ return not_hold
+```
+
### Go:
```go
diff --git a/problems/kamacoder/0044.开发商购买土地.md b/problems/kamacoder/0044.开发商购买土地.md
index 37bb98ed..ea2c696e 100644
--- a/problems/kamacoder/0044.开发商购买土地.md
+++ b/problems/kamacoder/0044.开发商购买土地.md
@@ -388,3 +388,85 @@ if __name__ == "__main__":
main()
```
+### C
+
+前缀和
+```c
+#include
+#include
+
+int main()
+{
+ int n = 0, m = 0, ret_ver = 0, ret_hor = 0;
+
+ // 读取行和列的值
+ scanf("%d%d", &n, &m);
+ // 动态分配数组a(横)和b(纵)的空间
+ int *a = (int *)malloc(sizeof(int) * n);
+ int *b = (int *)malloc(sizeof(int) * m);
+
+ // 初始化数组a和b
+ for (int i = 0; i < n; i++)
+ {
+ a[i] = 0;
+ }
+ for (int i = 0; i < m; i++)
+ {
+ b[i] = 0;
+ }
+
+ // 读取区块权值并计算每行和每列的总权值
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < m; j++)
+ {
+ int tmp;
+ scanf("%d", &tmp);
+ a[i] += tmp;
+ b[j] += tmp;
+ }
+ }
+
+ // 计算每列以及每行的前缀和
+ for (int i = 1; i < n; i++)
+ {
+ a[i] += a[i - 1];
+ }
+ for (int i = 1; i < m; i++)
+ {
+ b[i] += b[i - 1];
+ }
+
+ // 初始化ret_ver和ret_hor为最大可能值
+ ret_hor = a[n - 1];
+ ret_ver = b[m - 1];
+
+ // 计算按行划分的最小差异
+ int ret2 = 0;
+ while (ret2 < n)
+ {
+ ret_hor = (ret_hor > abs(a[n - 1] - 2 * a[ret2])) ? abs(a[n - 1] - 2 * a[ret2]) : ret_hor;
+ // 原理同列,但更高级
+ ret2++;
+ }
+ // 计算按列划分的最小差异
+ int ret1 = 0;
+ while (ret1 < m)
+ {
+ if (ret_ver > abs(b[m - 1] - 2 * b[ret1]))
+ {
+ ret_ver = abs(b[m - 1] - 2 * b[ret1]);
+ }
+ ret1++;
+ }
+
+ // 输出最小差异
+ printf("%d\n", (ret_ver <= ret_hor) ? ret_ver : ret_hor);
+
+ // 释放分配的内存
+ free(a);
+ free(b);
+ return 0;
+}
+
+```
diff --git a/problems/kamacoder/0058.区间和.md b/problems/kamacoder/0058.区间和.md
index 5125f5f8..23e7189a 100644
--- a/problems/kamacoder/0058.区间和.md
+++ b/problems/kamacoder/0058.区间和.md
@@ -264,6 +264,7 @@ if __name__ == "__main__":
```
+
### JavaScript
``` JavaScript
@@ -312,3 +313,47 @@ function prefixSum() {
```
+
+### C
+
+```C
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ int num;
+ // 读取数组长度
+ scanf("%d", &num);
+
+ // 使用动态内存分配而不是静态数组,以适应不同的输入大小
+ int *a = (int *)malloc((num + 1) * sizeof(int));
+
+ // 初始化前缀和数组的第一个元素为0
+ a[0] = 0;
+
+ // 读取数组元素并计算前缀和
+ for (int i = 1; i <= num; i++)
+ {
+ int mm;
+ scanf("%d", &mm);
+ // 累加前缀和
+ a[i] = a[i - 1] + mm;
+ }
+
+ int m, n;
+ // 循环读取区间并计算区间和,直到输入结束
+ // scanf()返回成功匹配和赋值的个数,到达文件末尾则返回 EOF
+ while (scanf("%d%d", &m, &n) == 2)
+ {
+ // 输出区间和,注意区间是左闭右开,因此a[n+1]是包含n的元素的前缀和
+ printf("%d\n", a[n+1] - a[m]);
+ }
+
+ // 释放之前分配的内存
+ free(a);
+ return 0;
+}
+
+```
+