Swift教室 Swift と競技プログラミングの教室

33. Unique Paths

読了目安 約1分

DP / LeetCode 62 (Medium) — 格子上の経路数を 2 次元 DP で数える。

この章の目次

問題

LeetCode 62. Unique Paths(Medium / カテゴリ: DP)

m 行 n 列の格子があり、ロボットが左上のマスにいます。 ロボットは右か下にしか動けません。 右下のマスに到達する経路が何通りあるかを返してください。 m と n はそれぞれ 100 以下です。

考え方

ヒント 1

状態を dp[i][j] = 「マス (i, j) に到達する経路の数」と定めます。 答えは右下のマスの値です。

ヒント 2

マス (i, j) には上か左からしか入れません。 遷移は dp[i][j] = dp[i-1][j] + dp[i][j-1] です。 初期条件は最上行と最左列で、動き方が 1 通りしかないのですべて 1 です。

Swift 実装のポイント

  • 2 次元配列は [[Int]](repeating: [Int](repeating: 1, count: n), count: m) で作ります。初期値を 1 にすると、最上行・最左列の初期条件が同時に済みます。
  • m == 1n == 1 のとき 1..<1 は空範囲になり、ループは 1 回も回りません(実行時エラーにはなりません)。
  • 遷移が直前の行しか見ないので、1 行分の配列を使い回せば空間 O(n) にできます。
模範解答
Swift
class Solution {
    func uniquePaths(_ m: Int, _ n: Int) -> Int {
        var dp = [[Int]](repeating: [Int](repeating: 1, count: n), count: m)
        for i in 1..<m {
            for j in 1..<n {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
            }
        }
        return dp[m - 1][n - 1]
    }
}

計算量: O(mn)。