930 Binary Subarrays With Sum 和相同的二元子數組
Description:
Given an n x n array of integers matrix, return the minimum sum of any falling path through matrix.
A falling path starts at any element in the first row and chooses the element in the next row that is either directly below or diagonally left/right. Specifically, the next element from position (row, col) will be (row + 1, col - 1), (row + 1, col), or (row + 1, col + 1).
Example:
Example 1:
Input: matrix = [[2,1,3],[6,5,4],[7,8,9]]
Output: 13
Explanation: There are two falling paths with a minimum sum as shown.
Example 2:
Input: matrix = [[-19,57],[-40,-5]]
Output: -59
Explanation: The falling path with a minimum sum is shown.
Constraints:
n == matrix.length == matrix[i].length
1 <= n <= 100
-100 <= matrix[i][j] <= 100
題目描述:
給你一個 n x n 的 方形 整數數組 matrix ,請你找出並返回通過 matrix 的下降路徑 的 最小和 。
下降路徑 可以從第一行中的任何元素開始,並從每一行中選擇一個元素。在下一行選擇的元素和當前行所選元素最多相隔一列(即位於正下方或者沿對角線向左或者向右的第一個元素)。具體來說,位置 (row, col) 的下一個元素應當是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。
示例 :
示例 1:
輸入:matrix = [[2,1,3],[6,5,4],[7,8,9]]
輸出:13
解釋:下面是兩條和最小的下降路徑,用加粗+斜體標註:
[[2,1,3], [[2,1,3],
[6,5,4], [6,5,4],
[7,8,9]] [7,8,9]]
示例 2:
輸入:matrix = [[-19,57],[-40,-5]]
輸出:-59
解釋:下面是一條和最小的下降路徑,用加粗+斜體標註:
[[-19,57],
[-40,-5]]
示例 3:
輸入:matrix = [[-48]]
輸出:-48
提示:
n == matrix.length
n == matrix[i].length
1 <= n <= 100
-100 <= matrix[i][j] <= 100
思路:
動態規劃
設 dp[i][j] 表示走到 matrix[i][j] 時的最小代價
動態轉移方程 dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1]) + matrix[i][j], 邊界單獨考慮
注意到只與上一行有關, 可以用滾動數組將空間複雜度壓縮爲 O(n)
時間複雜度爲 O(n ^ 2), 空間複雜度爲 O(n)
代碼:
C++:
class Solution
{
public:
int minFallingPathSum(vector<vector<int>>& matrix)
{
vector<int> dp(matrix.front());
for (int i = 1, n = matrix.size(); i < n; i++)
{
vector<int> cur(dp);
for (int j = 0; j < n; j++) cur[j] = (j == 0 ? min(dp[j], dp[j + 1]) : (j == n - 1 ? min(dp[j], dp[j - 1]) : min({ dp[j], dp[j + 1], dp[j - 1] }))) + matrix[i][j];
dp = cur;
}
return *min_element(dp.begin(), dp.end());
}
};
Java:
class Solution {
public int minFallingPathSum(int[][] matrix) {
int n = matrix.length, dp[] = new int[n], result = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) dp[i] = matrix[0][i];
for (int i = 1; i < n; i++) {
int[] cur = new int[n];
for (int j = 0; j < n; j++) cur[j] = dp[j];
for (int j = 0; j < n; j++) cur[j] = (j == 0 ? Math.min(dp[j], dp[j + 1]) : (j == n - 1 ? Math.min(dp[j], dp[j - 1]) : Math.min(Math.min(dp[j], dp[j + 1]), dp[j - 1]))) + matrix[i][j];
dp = cur;
}
for (int i = 0; i < n; i++) result = Math.min(result, dp[i]);
return result;
}
}
Python:
class Solution:
def minFallingPathSum(self, matrix: List[List[int]]) -> int:
dp, n = matrix[0], len(matrix)
for i in range(1, n):
cur = dp[:]
for j in range(n):
cur[j] = (min(dp[j], dp[j - 1], dp[j + 1]) if 0 < j < n - 1 else min(dp[j], dp[j + 1]) if not j else min(dp[j], dp[j - 1])) + matrix[i][j]
dp = cur
return min(dp)