Skip to content

Commit aeff1d6

Browse files
Merge branch 'master' into master
2 parents 0f5a208 + d35af50 commit aeff1d6

7 files changed

+295
-27
lines changed

problems/0188.买卖股票的最佳时机IV.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,47 @@ func max188(a, b int) int {
404404
}
405405
```
406406

407+
版本三:空间优化版本
408+
409+
```go
410+
func maxProfit(k int, prices []int) int {
411+
n := len(prices)
412+
// k次交易,2 * k种状态
413+
// 状态从1开始计算,避免判断
414+
// 奇数时持有(保持或买入)
415+
// 偶数时不持有(保持或卖出)
416+
dp := make([][]int, 2)
417+
dp[0] = make([]int, k * 2 + 1)
418+
dp[1] = make([]int, k * 2 + 1)
419+
420+
// 奇数状态时持有,i += 2
421+
for i := 1; i <= k * 2; i += 2 {
422+
dp[0][i] = -prices[0]
423+
}
424+
425+
for i := 1; i < len(prices); i++ {
426+
for j := 1; j <= k * 2; j++ {
427+
if j % 2 == 1 {
428+
dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - 1] - prices[i])
429+
} else {
430+
dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - 1] + prices[i])
431+
}
432+
}
433+
}
434+
435+
return dp[(n - 1) % 2][k * 2]
436+
}
437+
438+
func max(a, b int) int {
439+
if a > b {
440+
return a
441+
}
442+
return b
443+
}
444+
```
445+
446+
447+
407448
### JavaScript:
408449

409450
```javascript
@@ -558,3 +599,4 @@ impl Solution {
558599
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
559600
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
560601
</a>
602+

problems/0309.最佳买卖股票时机含冷冻期.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,42 @@ func max(a, b int) int {
357357
}
358358
```
359359

360+
```go
361+
// 一维优化版本
362+
// 时间复杂度O(n), 空间复杂度O(1)
363+
func maxProfit(prices []int) int {
364+
365+
// 0: 持有,一直持有和买入
366+
// 1: 不持有,一直不持有(不包含前一天卖出,因为这样的一天是冷静期,状态有区别)
367+
// 2:不持有,今天卖出
368+
// 3:冷静期,前一天卖出(一直不持有)
369+
dp0, dp1, dp2, dp3 := -prices[0], 0, 0, 0
370+
371+
n := len(prices)
372+
373+
for i := 1; i < n; i++ {
374+
t0 := max(dp0, max(dp1, dp3)-prices[i])
375+
t1 := max(dp1, dp3)
376+
t2 := dp0 + prices[i]
377+
t3 := dp2
378+
379+
// 更新
380+
dp0, dp1, dp2, dp3 = t0, t1, t2, t3
381+
}
382+
383+
return max(dp1, max(dp2, dp3))
384+
}
385+
386+
func max(a, b int) int {
387+
if a > b {
388+
return a
389+
}
390+
return b
391+
}
392+
```
393+
394+
395+
360396
### Javascript:
361397

362398
> 不同的状态定义 感觉更容易理解些
@@ -540,3 +576,4 @@ impl Solution {
540576
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
541577
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
542578
</a>
579+

problems/0503.下一个更大元素II.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ class Solution {
168168
```
169169

170170
### Python:
171+
> 版本一:
171172

172173
```python
173174
class Solution:
@@ -181,6 +182,34 @@ class Solution:
181182
stack.append(i%len(nums))
182183
return dp
183184
```
185+
186+
> 版本二:针对版本一的优化
187+
188+
```python3
189+
class Solution:
190+
def nextGreaterElements(self, nums: List[int]) -> List[int]:
191+
res = [-1] * len(nums)
192+
stack = []
193+
#第一次遍历nums
194+
for i, num in enumerate(nums):
195+
while stack and num > nums[stack[-1]]:
196+
res[stack[-1]] = num
197+
stack.pop()
198+
stack.append(i)
199+
#此时stack仍有剩余,有部分数‘无下一个更大元素’待修正
200+
#第二次遍历nums
201+
for num in nums:
202+
#一旦stack为空,就表明所有数都有下一个更大元素,可以返回结果
203+
if not stack:
204+
return res
205+
while stack and num > nums[stack[-1]]:
206+
res[stack[-1]] = num
207+
stack.pop()
208+
#不要将已经有下一个更大元素的数加入栈,这样会重复赋值,只需对第一次遍历剩余的数再尝试寻找下一个更大元素即可
209+
#最后仍有部分最大数无法有下一个更大元素,返回结果
210+
return res
211+
```
212+
184213
### Go:
185214

186215
```go
@@ -203,7 +232,6 @@ func nextGreaterElements(nums []int) []int {
203232
return result
204233
}
205234
```
206-
207235
### JavaScript:
208236

209237
```JS

problems/0701.二叉搜索树中的插入操作.md

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -283,32 +283,10 @@ class Solution:
283283
return TreeNode(val)
284284
self.traversal(root, val)
285285
return root
286-
287286
```
288287

289288
递归法(版本二)
290289
```python
291-
class Solution:
292-
def insertIntoBST(self, root, val):
293-
if root is None:
294-
return TreeNode(val)
295-
parent = None
296-
cur = root
297-
while cur:
298-
parent = cur
299-
if val < cur.val:
300-
cur = cur.left
301-
else:
302-
cur = cur.right
303-
if val < parent.val:
304-
parent.left = TreeNode(val)
305-
else:
306-
parent.right = TreeNode(val)
307-
return root
308-
```
309-
310-
递归法(版本三)
311-
```python
312290
class Solution:
313291
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
314292
if root is None or root.val == val:
@@ -326,7 +304,7 @@ class Solution:
326304
return root
327305
```
328306

329-
递归法(版本四
307+
递归法(版本三
330308
```python
331309
class Solution:
332310
def insertIntoBST(self, root, val):
@@ -340,10 +318,9 @@ class Solution:
340318
root.right = self.insertIntoBST(root.right, val)
341319

342320
return root
343-
344321
```
345322

346-
迭代法
323+
迭代法(版本一)
347324
```python
348325
class Solution:
349326
def insertIntoBST(self, root, val):
@@ -366,10 +343,53 @@ class Solution:
366343
else:
367344
parent.right = node # 将新节点连接到父节点的右子树
368345

346+
return root
347+
```
348+
349+
迭代法(版本二)
350+
```python
351+
class Solution:
352+
def insertIntoBST(self, root, val):
353+
if root is None:
354+
return TreeNode(val)
355+
parent = None
356+
cur = root
357+
while cur:
358+
parent = cur
359+
if val < cur.val:
360+
cur = cur.left
361+
else:
362+
cur = cur.right
363+
if val < parent.val:
364+
parent.left = TreeNode(val)
365+
else:
366+
parent.right = TreeNode(val)
369367
return root
368+
```
369+
370+
迭代法(精简)
371+
```python
372+
class Solution:
373+
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
374+
if not root: # 如果根节点为空,创建新节点作为根节点并返回
375+
return TreeNode(val)
376+
cur = root
377+
while cur:
378+
if val < cur.val:
379+
if not cur.left: # 如果此时父节点的左子树为空
380+
cur.left = TreeNode(val) # 将新节点连接到父节点的左子树
381+
return root
382+
else:
383+
cur = cur.left
384+
elif val > cur.val:
385+
if not cur.right: # 如果此时父节点的左子树为空
386+
cur.right = TreeNode(val) # 将新节点连接到父节点的右子树
387+
return root
388+
else:
389+
cur = cur.right
370390

371-
372391
```
392+
373393
-----
374394
### Go
375395

problems/0714.买卖股票的最佳时机含手续费(动态规划).md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,20 @@ class Solution:
188188
return max(dp[-1][0], dp[-1][1])
189189
```
190190

191+
```python
192+
class Solution:
193+
def maxProfit(self, prices: List[int], fee: int) -> int:
194+
# 持有股票手上的最大現金
195+
hold = -prices[0] - fee
196+
# 不持有股票手上的最大現金
197+
not_hold = 0
198+
for price in prices[1:]:
199+
new_hold = max(hold, not_hold - price - fee)
200+
new_not_hold = max(not_hold, hold + price)
201+
hold, not_hold = new_hold, new_not_hold
202+
return not_hold
203+
```
204+
191205
### Go:
192206

193207
```go

problems/kamacoder/0044.开发商购买土地.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,85 @@ if __name__ == "__main__":
388388
main()
389389

390390
```
391+
### C
392+
393+
前缀和
394+
```c
395+
#include <stdlib.h>
396+
#include <stdio.h>
397+
398+
int main()
399+
{
400+
int n = 0, m = 0, ret_ver = 0, ret_hor = 0;
401+
402+
// 读取行和列的值
403+
scanf("%d%d", &n, &m);
404+
// 动态分配数组a(横)和b(纵)的空间
405+
int *a = (int *)malloc(sizeof(int) * n);
406+
int *b = (int *)malloc(sizeof(int) * m);
407+
408+
// 初始化数组a和b
409+
for (int i = 0; i < n; i++)
410+
{
411+
a[i] = 0;
412+
}
413+
for (int i = 0; i < m; i++)
414+
{
415+
b[i] = 0;
416+
}
417+
418+
// 读取区块权值并计算每行和每列的总权值
419+
for (int i = 0; i < n; i++)
420+
{
421+
for (int j = 0; j < m; j++)
422+
{
423+
int tmp;
424+
scanf("%d", &tmp);
425+
a[i] += tmp;
426+
b[j] += tmp;
427+
}
428+
}
429+
430+
// 计算每列以及每行的前缀和
431+
for (int i = 1; i < n; i++)
432+
{
433+
a[i] += a[i - 1];
434+
}
435+
for (int i = 1; i < m; i++)
436+
{
437+
b[i] += b[i - 1];
438+
}
439+
440+
// 初始化ret_ver和ret_hor为最大可能值
441+
ret_hor = a[n - 1];
442+
ret_ver = b[m - 1];
443+
444+
// 计算按行划分的最小差异
445+
int ret2 = 0;
446+
while (ret2 < n)
447+
{
448+
ret_hor = (ret_hor > abs(a[n - 1] - 2 * a[ret2])) ? abs(a[n - 1] - 2 * a[ret2]) : ret_hor;
449+
// 原理同列,但更高级
450+
ret2++;
451+
}
452+
// 计算按列划分的最小差异
453+
int ret1 = 0;
454+
while (ret1 < m)
455+
{
456+
if (ret_ver > abs(b[m - 1] - 2 * b[ret1]))
457+
{
458+
ret_ver = abs(b[m - 1] - 2 * b[ret1]);
459+
}
460+
ret1++;
461+
}
462+
463+
// 输出最小差异
464+
printf("%d\n", (ret_ver <= ret_hor) ? ret_ver : ret_hor);
465+
466+
// 释放分配的内存
467+
free(a);
468+
free(b);
469+
return 0;
470+
}
471+
472+
```

0 commit comments

Comments
 (0)