Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions 63-Unique-Paths-II/note.md
Original file line number Diff line number Diff line change
@@ -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 は各行を持つ必要はない。
各マスへの行き方は、そのマスの上のマスへの行き方と左のマスへの行き方の合計であるが、ある行を計算し終わったとき、次の行の各マスにおいて、上のマスからの寄与は今保持している行そのもの。左からの分だけ計算すればいい。

@MA-yo-TA MA-yo-TA Aug 21, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

考えてみれば当たり前で、 step3 のやり方は

  1. 最初に 0 を詰める
  2. 上の行を += で足す

なので、そもそもコピーしていただけだったと考えると無駄なデータを保存していた。

21 changes: 21 additions & 0 deletions 63-Unique-Paths-II/step1.py
Original file line number Diff line number Diff line change
@@ -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)]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[[0] * num_columns for _ in range(num_rows)]

のほうがシンプルだと思います。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一応、このあたりのオブジェクトの理屈が分かっているかは確認しておいてください。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.wrv8idqm5j2b

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

お二人ともありがとうございます。確認しておきます。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

空間計算量 O(num_columns) で解く方法もあります。興味があればぜひ考えてみて下さい。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。こうやれば良さそうというのが頭にあるのでそれを実装してみます。

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]
19 changes: 19 additions & 0 deletions 63-Unique-Paths-II/step2.py
Original file line number Diff line number Diff line change
@@ -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]
20 changes: 20 additions & 0 deletions 63-Unique-Paths-II/step3.py
Original file line number Diff line number Diff line change
@@ -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]
19 changes: 19 additions & 0 deletions 63-Unique-Paths-II/step4.py
Original file line number Diff line number Diff line change
@@ -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]