-
Notifications
You must be signed in to change notification settings - Fork 0
63. Unique Paths II #32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # 63. Unique Paths II | ||
|
|
||
| - sol1.py: dpでかいた | ||
| - sol2.py: 初期化方法と変数名を改善 | ||
|
|
||
| https://github.com/olsen-blue/Arai60/pull/34#pullrequestreview-2636297197 | ||
| > コンパイラ言語ではif文(機械語にしたときの分岐命令)って(分岐予測に失敗するとパイプラインの工程を最初からやり直さないといけないので)他の命令より時間がかかるんです | ||
| > なので、可読性の面でも速度の面でもこのfor文は分けた方がよりよいですね | ||
| >でも、Pythonはインタプリタ言語(そもそもプログラムの解釈・実行に大量に分岐命令が使われてると思う)なので速度の観点では気にするような速度差は生まれないかもしれません | ||
|
|
||
| これは勉強になった。 | ||
| つまり、CやRustなどんコンパイラ言語では、分岐予測に失敗するとオーバーヘッドが発生するので、for文内のif文はなるべく分けた方が良い。 | ||
| つまり、事前に決まっている分岐(0行目or0列目など)はfor文の外で行った方が良い。 | ||
| しかし、Pythonの場合はこれを気にする必要はなさそう。 | ||
|
|
||
|
|
||
| https://github.com/Fuminiton/LeetCode/pull/34#discussion_r2052772608 | ||
| > [0][0]にアクセスする前に一応チェックしてもいいかもしれませんね。問題文に制約があるにせよ。 | ||
|
|
||
| これはたまたまできていた | ||
|
|
||
| https://algo-method.com/descriptions/78 | ||
| 配るDPともらうDP | ||
| 配るDPで書いた:sol3.py |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| class Solution: | ||
| def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: | ||
| if not obstacleGrid or not obstacleGrid[0]: | ||
| return 0 | ||
|
|
||
| num_rows, num_cols = len(obstacleGrid), len(obstacleGrid[0]) | ||
|
|
||
| EMPTY = 0 | ||
|
|
||
| if obstacleGrid[0][0] != EMPTY: | ||
| return 0 | ||
|
|
||
| unique_paths_per_row = [1] + [0] * (num_cols - 1) | ||
|
|
||
| col = 1 | ||
| while col < num_cols and obstacleGrid[0][col] == EMPTY: | ||
| unique_paths_per_row[col] = 1 | ||
| col += 1 | ||
|
Comment on lines
+15
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. というかこの箇所なくして後ろの for row in range(0, num_rows):あるマスの値が,その左のマスの値と上のマスの値の和で決まるという仕組みからすると,コメント先の部分の処理を後ろのforループに含んでしまうのも不自然ではないと感じます.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ああ、その通りですね。 |
||
|
|
||
| for row in range(1, num_rows): | ||
| for col in range(0, num_cols): | ||
| if obstacleGrid[row][col] != EMPTY: | ||
| unique_paths_per_row[col] = 0 | ||
| continue | ||
| if col == 0: | ||
| continue | ||
| unique_paths_per_row[col] += unique_paths_per_row[col - 1] | ||
|
|
||
| return unique_paths_per_row[-1] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| class Solution: | ||
| def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: | ||
| if not obstacleGrid or not obstacleGrid[0]: | ||
| return 0 | ||
|
|
||
| n_row, n_col = len(obstacleGrid), len(obstacleGrid[0]) | ||
|
|
||
| unique_paths_per_row = [0] * n_col | ||
| unique_paths_per_row[0] = 0 if obstacleGrid[0][0] else 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. そうですね。分かりやすさの意味でもその方が良いと思うので採用させていただきます。 |
||
|
|
||
| for row in range(n_row): | ||
| for col in range(n_col): | ||
| if obstacleGrid[row][col]: | ||
| unique_paths_per_row[col] = 0 | ||
| continue | ||
| elif col > 0: | ||
| unique_paths_per_row[col] += unique_paths_per_row[col - 1] | ||
|
Comment on lines
+13
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 正誤には関係ありませんが,
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. そのとおりですね。If...continueとするならelifではなくifの方が適切ですね。 |
||
|
|
||
| return unique_paths_per_row[-1] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| class Solution: | ||
| def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: | ||
| if not obstacleGrid or not obstacleGrid[0]: | ||
| return 0 | ||
|
|
||
| n_row, n_col = len(obstacleGrid), len(obstacleGrid[0]) | ||
|
|
||
| unique_paths_per_row = [0] * n_col | ||
| if obstacleGrid[0][0] == 1: | ||
| return 0 | ||
| unique_paths_per_row[0] = 1 | ||
|
|
||
| for row in range(n_row): | ||
| for col in range(n_col): | ||
| if obstacleGrid[row][col]: | ||
| unique_paths_per_row[col] = 0 | ||
| elif col > 0: | ||
| unique_paths_per_row[col] += unique_paths_per_row[col - 1] | ||
|
|
||
| return unique_paths_per_row[-1] |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. メモリ使用量が増えるのをやむなしで、2次元配列(フルのテーブル)で書いたほうが、配るDPは分かりやすいと思いました。また、最終行は配らなくていいとか、障害物があったら0に潰して配れない(こっちは最終行も処理する必要がある)、など制御が比較的面倒で、配るよりも貰う方が書きやすそうに感じました。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 「配るよりも貰う方が書きやすそう」は同意します。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
そのとおりで、処理的には問題ないのですが、書きやすさ(バグの埋め込みやすさ)・読みやすさの観点からは、2次元配列の方が優れていそうだな、と感じました。 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| class Solution: | ||
| def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: | ||
| if not obstacleGrid or not obstacleGrid[0]: | ||
| return 0 | ||
|
|
||
| n_row, n_col = len(obstacleGrid), len(obstacleGrid[0]) | ||
|
|
||
| unique_paths_per_row = [0] * n_col | ||
| unique_paths_per_row[0] = 0 if obstacleGrid[0][0] else 1 | ||
|
|
||
| for row in range(n_row): | ||
| unique_paths_next_row = [0] * n_col | ||
| for col in range(n_col): | ||
| if obstacleGrid[row][col]: | ||
| unique_paths_per_row[col] = 0 | ||
| continue | ||
|
|
||
| paths = unique_paths_per_row[col] | ||
| if paths == 0: | ||
| continue | ||
|
|
||
| if col + 1 < n_col: | ||
| unique_paths_per_row[col + 1] += paths | ||
| if row + 1 < n_row: | ||
| unique_paths_next_row[col] += paths | ||
|
|
||
| if row + 1 < n_row: | ||
| unique_paths_per_row = unique_paths_next_row | ||
|
Comment on lines
+11
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. これは単に好みの問題ですが,
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 同意します。自分が素直に思いついたのもsol2.pyの方でした。 |
||
|
|
||
| return unique_paths_per_row[-1] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
好みの問題ですが
colがこのwhile内でしか使われていないのでfor文にしても良いと思いました.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
なるほど、その書き方もありますね。
ただ今回は「while の条件式の中にループが続く条件を書きたい」という意図で現状のものを採用しようと思います。