Skip to content

Commit 98159d7

Browse files
author
lucifer
committed
feat: Minimum Dropping Path Sum
1 parent f46ffdb commit 98159d7

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
249249
- [Sort-String-by-Flipping](./problems/Sort-String-by-Flipping.md) 🆕
250250
- [Number of Substrings with Single Character Difference](./problems/Number-of-Substrings-with-Single-Character-Difference.md) 🆕
251251
- [Bus Fare](./problems/Bus-Fare.md) 🆕 👍
252+
- [Minimum Dropping Path Sum](./problems/Minimum-Dropping-Path-Sum.md) 🆕
252253

253254
- [0002. 两数相加](./problems/2.add-two-numbers.md) 👍
254255
- [0003. 无重复字符的最长子串](./problems/3.longest-substring-without-repeating-characters.md)

SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
- [Consecutive Wins](./problems/consecutive-wins.md) 🆕
106106
- [Number of Substrings with Single Character Difference](./problems/Number-of-Substrings-with-Single-Character-Difference.md) 🆕
107107
- [Bus Fare](./problems/Bus-Fare.md) 🆕 👍
108+
- [Minimum Dropping Path Sum](./problems/Minimum-Dropping-Path-Sum.md) 🆕
108109
- [0002. 两数相加](./problems/2.add-two-numbers.md)
109110
- [0003. 无重复字符的最长子串](./problems/3.longest-substring-without-repeating-characters.md)
110111
- [0005. 最长回文子串](./problems/5.longest-palindromic-substring.md)

problems/Minimum-Dropping-Path-Sum.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# 题目地址(Minimum Dropping Path Sum)
2+
3+
https://binarysearch.com/problems/Minimum-Dropping-Path-Sum
4+
5+
## 题目描述
6+
7+
```
8+
You are given a two-dimensional list of integers matrix. Return the minimum sum you can get by taking a number in each row with the constraint that any row-adjacent numbers cannot be in the same column.
9+
10+
Constraints
11+
12+
1 ≤ n ≤ 250 where n is the number of rows in matrix
13+
2 ≤ m ≤ 250 where m is the number of columns in matrix
14+
Example 1
15+
Input
16+
matrix = [
17+
[4, 5, -2],
18+
[2, 6, 1],
19+
[3, 1, 2]
20+
]
21+
Output
22+
1
23+
Explanation
24+
We can take -2 from the first row, 2 from the second row, and 1 from the last row.
25+
26+
Example 2
27+
Input
28+
matrix = [
29+
[3, 0, 3],
30+
[2, 1, 3],
31+
[-2, 3, 0]
32+
]
33+
Output
34+
1
35+
Explanation
36+
We can take 0 from the first row, 3 from the second row, and -2 from the last row.
37+
```
38+
39+
## 前置知识
40+
41+
- [动态规划](https://github.com/azl397985856/leetcode/blob/master/thinkings/dynamic-programming.md "动态规划")
42+
43+
## 公司
44+
45+
- 暂无
46+
47+
## 思路
48+
49+
这道题是不同路径(或者杨辉三角)的换皮题。
50+
51+
这道题是让我们每一行选择一个数,使得数字和最小。唯一的限制是相邻行拿的数字不能列相同(其实就是不能上下紧挨着拿)。
52+
53+
一个可能的暴力思路是:
54+
55+
- 先取第一行。第一行有 n (n 为列数)个选择,那就挨个试。
56+
- 接下来取第二行。第二行有 n-1 个选择,那就挨个试。
57+
- 接下来取第三行。第三行有 n-1 个选择,那就挨个试。
58+
- 。。。
59+
60+
不要小看暴力法, 这是一种解决问题的思维习惯。
61+
62+
如果你将上面的过程画成一棵树的话,那么可以看出时间复杂度大概是和底层的节点数是一个数量级的,是指数级别的。就算不画树,你也不难看出大概的计算次数是 n _(n -1) _ (n - 1) ...(一共 m - 1 个 n -1)。那么我们可以优化么?
63+
64+
实际上是可以的。我们先不考虑题目的限制”相邻行拿的数字不能列相同“。那么我们的策略就变成了贪婪, 只要每一行都取最小的不就行了?时间复杂度是 $O(m * n)$。
65+
66+
那么加上这个限制会有什么不同么?以题目的例子为例:
67+
68+
```
69+
matrix = [
70+
[3, 0, 3],
71+
[2, 1, 3],
72+
[-2, 3, 0]
73+
]
74+
```
75+
76+
贪心的做法第一行要选 0,第二行要选 1,不过违反了限制。那我们有必要把所有的选择第一行和第二行的组合计算出来么(就像上面的暴力法那样)?其实我们只**记录上一行的最小和次小值**即可。如果出现了上面的情况,那么我们可以考虑:
77+
78+
- 选择 1 和上一行次小值(3 + 1)
79+
- 选择行次小值和上一行最小值(2 + 0)
80+
81+
剩下的逻辑也是如此。
82+
83+
最终我们返回**选择到达**最后一行的**最小值**即可。
84+
85+
## 代码
86+
87+
代码支持:Python3
88+
89+
Python3 Code:
90+
91+
```py
92+
class Solution:
93+
def solve(self, matrix):
94+
dp = [(0, -1)]
95+
m, n = len(matrix), len(matrix[0])
96+
for i in range(m):
97+
next_dp = [(float("inf"), -1), (float("inf"), -1)]# (smallest, 2nd smallest)
98+
for j in range(n):
99+
for v, k in dp:
100+
if k == j:
101+
continue
102+
nxt = matrix[i][j] + v
103+
if nxt < next_dp[0][0]:
104+
next_dp = [(nxt, j), next_dp[0]]
105+
elif nxt < next_dp[1][0]:
106+
next_dp[1] = (nxt, j)
107+
break
108+
dp = next_dp # rolling array
109+
return dp[0][0]
110+
111+
```
112+
113+
**复杂度分析**
114+
115+
- 时间复杂度:$O(m*n)$
116+
- 空间复杂度:$O(1)$ (使用了滚动数组优化)
117+
118+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。

0 commit comments

Comments
 (0)