解決策:境界パス外
32138 ワード
これは一連のleetcode解決説明の一部です.あなたがこの解決が好きであるか、それが役に立つとわかるならば、このポストとmy solution post on Leetcode's forums .
にジャンプします.Solution Idea || コードJavaScript | Python | Java | C++ )
にジャンプします.Problem Description || コードJavaScript | Python | Java | C++ )
可能な経路の数が4 ^ maxmoveであるので、この問題のためのブルートフォース解決はあまりにも長いでしょう.重複パスを含むほとんどの問題の場合と同様に、この問題は、動的プログラミング(DP)アプローチの助けを借りて、これらのオーバーラップパスを結合することによって簡素化することができる.
この例では、各セル(DP[d][i][j])は、Dが移動の数であり、IとJが開始位置の座標であるというDP行列を作成することができる.d = 1からd = maxmoveまでこのDP行列を構築することができます.
DPを構築するには、D = 1のときに開始値を入力することによって開始することができます.そこから、私たちはDのために残りの値を通して反復することができます、そして、各々のセルは前の移動反復(D - 1)からの周囲の4つのセルの合計であるでしょう.
私たちが完全なmaxmoveをとらないどんな経路も含めたいので、解決(ANS)はそれからD =のためにすべての可能な値でi = startrowとj = startcolumnに対応するDPのセルの合計です.
境界チェックの必要性を防ぐことによって容易にするために、我々は0の値で満たされるDPのグリッド表現のすべての4つの側にバッファ行/コラムを加えることができます.
我々が現在のものを構築するためにDの以前の反復を使うだけで、我々はMaxLove深さの3 D行列の代わりに2つの2 Dマトリックス(DPCurr、DPLast)だけにDPを圧縮することによって、この解決でスペースを節約することができます.これを行うには、各繰り返しの間にdpcurrとdplastをスワップし、それを繰り返すとDPcurrの古い値を上書きするだけで行うことができます.我々はまた、我々は行くようにアンを追跡することができます.
また、各セル値式でモジュロ演算を使用することを忘れてはいけません. 時間複雑さ:n(n)は格子の次元であり、lは移動の最大数である 空間複雑度DP行列のO(n*m)
にジャンプします.Problem Description || Solution Idea )
にジャンプします.Problem Description || Solution Idea )
にジャンプします.Problem Description || Solution Idea )
にジャンプします.Problem Description || Solution Idea )
Leetcode問題は、1つの境界パス
説明
にジャンプします.Solution Idea || コードJavaScript | Python | Java | C++ )
There is an
m
xn
grid with a ball. The ball is initially at the position[startRow, startColumn]
. You are allowed to move the ball to one of the four adjacent four cells in the grid (possibly out of the grid crossing the grid boundary). You can apply at mostmaxMove
moves to the ball.Given the five integers
m
,n
,maxMove
,startRow
,startColumn
, return the number of paths to move the ball out of the grid boundary. Since the answer can be very large, return it modulo10^9 + 7
.
例:
Example 1: Input: m = 2, n = 2, maxMove = 2, startRow = 0, startColumn = 0 Output: 6 Visual:
Example 2: Input: m = 1, n = 3, maxMove = 3, startRow = 0, startColumn = 1 Output: 12 Visual:
制約
1 <= m, n <= 50
0 <= maxMove <= 50
0 <= startRow <= m
0 <= startColumn <= n
考え
にジャンプします.Problem Description || コードJavaScript | Python | Java | C++ )
可能な経路の数が4 ^ maxmoveであるので、この問題のためのブルートフォース解決はあまりにも長いでしょう.重複パスを含むほとんどの問題の場合と同様に、この問題は、動的プログラミング(DP)アプローチの助けを借りて、これらのオーバーラップパスを結合することによって簡素化することができる.
この例では、各セル(DP[d][i][j])は、Dが移動の数であり、IとJが開始位置の座標であるというDP行列を作成することができる.d = 1からd = maxmoveまでこのDP行列を構築することができます.
DPを構築するには、D = 1のときに開始値を入力することによって開始することができます.そこから、私たちはDのために残りの値を通して反復することができます、そして、各々のセルは前の移動反復(D - 1)からの周囲の4つのセルの合計であるでしょう.
私たちが完全なmaxmoveをとらないどんな経路も含めたいので、解決(ANS)はそれからD =のためにすべての可能な値でi = startrowとj = startcolumnに対応するDPのセルの合計です.
境界チェックの必要性を防ぐことによって容易にするために、我々は0の値で満たされるDPのグリッド表現のすべての4つの側にバッファ行/コラムを加えることができます.
我々が現在のものを構築するためにDの以前の反復を使うだけで、我々はMaxLove深さの3 D行列の代わりに2つの2 Dマトリックス(DPCurr、DPLast)だけにDPを圧縮することによって、この解決でスペースを節約することができます.これを行うには、各繰り返しの間にdpcurrとdplastをスワップし、それを繰り返すとDPcurrの古い値を上書きするだけで行うことができます.我々はまた、我々は行くようにアンを追跡することができます.
また、各セル値式でモジュロ演算を使用することを忘れてはいけません.
JavaScriptコード
にジャンプします.Problem Description || Solution Idea )
var findPaths = function(m, n, maxMove, startRow, startColumn) {
if (!maxMove) return 0
let dpCurr = Array.from({length: m+2}, () => new Uint32Array(n+2)),
dpLast = Array.from({length: m+2}, () => new Uint32Array(n+2))
for (let i = 1; i <= m; i++)
dpCurr[i][1]++, dpCurr[i][n]++
for (let j = 1; j <= n; j++)
dpCurr[1][j]++, dpCurr[m][j]++
let ans = dpCurr[startRow+1][startColumn+1]
for (let d = 1; d < maxMove; d++) {
[dpCurr, dpLast] = [dpLast, dpCurr]
for (let i = 1; i <= m; i++)
for (let j = 1; j <= n; j++)
dpCurr[i][j] = (dpLast[i-1][j] + dpLast[i+1][j] + dpLast[i][j-1] + dpLast[i][j+1]) % 1000000007
ans = (ans + dpCurr[startRow+1][startColumn+1]) % 1000000007
}
return ans
};
Pythonコード:
にジャンプします.Problem Description || Solution Idea )
class Solution:
def findPaths(self, m: int, n: int, maxMove: int, startRow: int, startColumn: int) -> int:
if maxMove == 0: return 0
dpCurr = [[0] * (n+2) for _ in range(m+2)]
dpLast = [[0] * (n+2) for _ in range(m+2)]
for i in range(1, m+1):
dpCurr[i][1] += 1
dpCurr[i][n] += 1
for j in range(1, n+1):
dpCurr[1][j] += 1
dpCurr[m][j] += 1
ans = dpCurr[startRow+1][startColumn+1]
for d in range(maxMove-1):
dpCurr, dpLast = dpLast, dpCurr
for i, j in product(range(1, m+1), range(1, n+1)):
dpCurr[i][j] = (dpLast[i-1][j] + dpLast[i+1][j] + dpLast[i][j-1] + dpLast[i][j+1]) % 1000000007
ans = (ans + dpCurr[startRow+1][startColumn+1]) % 1000000007
return ans
Javaコード:
にジャンプします.Problem Description || Solution Idea )
class Solution {
public int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
if (maxMove == 0) return 0;
int[][] dpCurr = new int[m+2][n+2], dpLast = new int[m+2][n+2];
for (int i = 1; i <= m; i++) {
dpCurr[i][1]++;
dpCurr[i][n]++;
}
for (int j = 1; j <= n; j++) {
dpCurr[1][j]++;
dpCurr[m][j]++;
}
int ans = dpCurr[startRow+1][startColumn+1];
for (int d = 1; d < maxMove; d++) {
int[][] temp = dpCurr;
dpCurr = dpLast;
dpLast = temp;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
dpCurr[i][j] = (int)(((long)dpLast[i-1][j] + dpLast[i+1][j] + dpLast[i][j-1] + dpLast[i][j+1]) % 1000000007L);
ans = (ans + dpCurr[startRow+1][startColumn+1]) % 1000000007;
}
return ans;
}
}
C ++コード:
にジャンプします.Problem Description || Solution Idea )
class Solution {
public:
int findPaths(int m, int n, int maxMove, int startRow, int startColumn) {
if (!maxMove) return 0;
vector<vector<int>> dpCurr(m+2, vector<int>(n+2)),
dpLast(m+2, vector<int>(n+2));
for (int i = 1; i <= m; i++)
dpCurr[i][1]++, dpCurr[i][n]++;
for (int j = 1; j <= n; j++)
dpCurr[1][j]++, dpCurr[m][j]++;
int ans = dpCurr[startRow+1][startColumn+1];
for (int d = 1; d < maxMove; d++) {
dpCurr.swap(dpLast);
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
dpCurr[i][j] = (int)(((long)dpLast[i-1][j] + dpLast[i+1][j] + dpLast[i][j-1] + dpLast[i][j+1]) % 1000000007L);
ans = (ans + dpCurr[startRow+1][startColumn+1]) % 1000000007;
}
return ans;
}
};
Reference
この問題について(解決策:境界パス外), 我々は、より多くの情報をここで見つけました https://dev.to/seanpgallivan/solution-out-of-boundary-paths-2jefテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol