diff --git a/63-Unique-Paths-II/note.md b/63-Unique-Paths-II/note.md new file mode 100644 index 0000000..c9381f3 --- /dev/null +++ b/63-Unique-Paths-II/note.md @@ -0,0 +1,35 @@ +# 63. Unique Paths II + +https://leetcode.com/problems/unique-paths-ii/ + +## step1(まず通す) + +考え方は https://leetcode.com/problems/unique-paths/ と同様で、「あるのマスへの行き方はそのマスの左と上への行き方の合計」。ただし、障害物があるところはいけないので 0。 + +スタート地点に障害物がある場合の扱いは少し迷ったが、左上から右下までの生き方が存在しない = 0 と考えそのようにした。 + +## step2(整形&他の人のコードを読む) + +https://github.com/h-masder/Arai60/pull/37 + +- ループの中でそのマスの左隣・下のインデックスが範囲内かをいちいち確認するとちょっと煩雑に見える可能性がある + - num_paths の 外側 1行1列を 0 埋めする + - 範囲チェックと後続処理をまとめて関数にする + +などが議論されている + +外側ゼロ埋めをやってみる。 + +## step3(10分以内にさっとかける * 3回) + +- キャメルケースをやめ obstacle_grid に +- 1 は OBSTACLE という定数でおいて意味がわかりやすいように + +## step4 + +空間計算量 O(num_colomuns) でやってみる + +アイディア: + +num_paths は各行を持つ必要はない。 +各マスへの行き方は、そのマスの上のマスへの行き方と左のマスへの行き方の合計であるが、ある行を計算し終わったとき、次の行の各マスにおいて、上のマスからの寄与は今保持している行そのもの。左からの分だけ計算すればいい。 diff --git a/63-Unique-Paths-II/step1.py b/63-Unique-Paths-II/step1.py new file mode 100644 index 0000000..3a4e213 --- /dev/null +++ b/63-Unique-Paths-II/step1.py @@ -0,0 +1,21 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: list[list[int]]) -> int: + num_rows = len(obstacleGrid) + num_columns = len(obstacleGrid[0]) + num_paths = [[0 for _ in range(num_columns)] for _ in range(num_rows)] + if obstacleGrid[0][0] == 1: + return 0 + + num_paths[0][0] = 1 + for row in range(num_rows): + for column in range(num_columns): + if obstacleGrid[row][column] == 1: + num_paths[row][column] = 0 + continue + + if column + 1 < num_columns: + num_paths[row][column + 1] += num_paths[row][column] + if row + 1 < num_rows: + num_paths[row + 1][column] += num_paths[row][column] + + return num_paths[-1][-1] diff --git a/63-Unique-Paths-II/step2.py b/63-Unique-Paths-II/step2.py new file mode 100644 index 0000000..7029c75 --- /dev/null +++ b/63-Unique-Paths-II/step2.py @@ -0,0 +1,19 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: list[list[int]]) -> int: + num_rows = len(obstacleGrid) + num_columns = len(obstacleGrid[0]) + num_paths = [[0 for _ in range(num_columns + 1)] for _ in range(num_rows + 1)] + if obstacleGrid[0][0] == 1: + return 0 + + num_paths[0][0] = 1 + for row in range(num_rows): + for column in range(num_columns): + if obstacleGrid[row][column] == 1: + num_paths[row][column] = 0 + continue + + num_paths[row][column + 1] += num_paths[row][column] + num_paths[row + 1][column] += num_paths[row][column] + + return num_paths[num_rows - 1][num_columns - 1] diff --git a/63-Unique-Paths-II/step3.py b/63-Unique-Paths-II/step3.py new file mode 100644 index 0000000..41dc0bc --- /dev/null +++ b/63-Unique-Paths-II/step3.py @@ -0,0 +1,20 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacle_grid: list[list[int]]) -> int: + OBSTACLE = 1 + if obstacle_grid[-1][-1] == OBSTACLE: + return 0 + + num_rows = len(obstacle_grid) + num_columns = len(obstacle_grid[0]) + num_paths = [[0 for _ in range(num_columns + 1)] for _ in range(num_rows + 1)] + num_paths[0][0] = 1 + for row in range(num_rows): + for column in range(num_columns): + if obstacle_grid[row][column] == OBSTACLE: + num_paths[row][column] = 0 + continue + + num_paths[row][column + 1] += num_paths[row][column] + num_paths[row + 1][column] += num_paths[row][column] + + return num_paths[num_rows - 1][num_columns - 1] diff --git a/63-Unique-Paths-II/step4.py b/63-Unique-Paths-II/step4.py new file mode 100644 index 0000000..c6a5cb5 --- /dev/null +++ b/63-Unique-Paths-II/step4.py @@ -0,0 +1,19 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacle_grid: list[list[int]]) -> int: + OBSTACLE = 1 + if obstacle_grid[-1][-1] == OBSTACLE: + return 0 + + num_rows = len(obstacle_grid) + num_columns = len(obstacle_grid[0]) + num_paths = [0] * (num_columns + 1) + num_paths[0] = 1 + for row in range(num_rows): + for column in range(num_columns): + if obstacle_grid[row][column] == OBSTACLE: + num_paths[column] = 0 + continue + + num_paths[column + 1] += num_paths[column] + + return num_paths[num_columns - 1]