-
Notifications
You must be signed in to change notification settings - Fork 0
62 unique paths #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
Open
MA-yo-TA
wants to merge
2
commits into
main
Choose a base branch
from
62-Unique-Paths
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
62 unique paths #32
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| # 62. Unique Paths | ||
|
|
||
| https://leetcode.com/problems/unique-paths/ | ||
|
|
||
| ## step1(まず通す) | ||
|
|
||
| ### 方法1 | ||
|
|
||
| 数学の問題でよくある設定。m - 1 回の下移動と n - 1 回の右移動を並べるときの並べ方の総数。 | ||
| `((m - 1) + (n - 1))!/((m - 1)! (n - 1)!)` | ||
|
|
||
| Python の整数は 64 bit 環境では sys.maxsize が `2 ^ 63 - 1` で、 10 進数で 18 桁ある。ただし、Python ではこれは int の最大値ではなくて、メモリが許せばもっと大きな整数も扱える。`2 ^ 7 - 1` で 1 byte なので、よほどメモリが厳しい環境でないならそこまで気にすることではなさそうか(少なくとも Python を使う用途ではそういう環境は少なそう) | ||
|
|
||
| ``` | ||
| # 手元の PC で実験 | ||
| $ python3 | ||
| >>> import sys | ||
| >>> sys.maxsize | ||
| 9223372036854775807 | ||
| >>> large = 10 ** 50 | ||
| >>> large | ||
| 100000000000000000000000000000000000000000000000000 | ||
| >>> type(large) | ||
| <class 'int'> | ||
| >>> sys.maxsize < large | ||
| True | ||
| ``` | ||
|
|
||
| ```python | ||
| from math import factorial | ||
|
|
||
|
|
||
| class Solution: | ||
| def uniquePaths(self, m: int, n: int) -> int: | ||
| return factorial(m + n - 2) // (factorial(m - 1) * factorial(n - 1)) | ||
| ``` | ||
|
|
||
| `m = <大きい>, n = 2` みたいに偏っていると、答えの大きさに制限があっても↑の素朴なやり方では計算過程で大きすぎる数が発生することがあるが、その場合でも分母の m - 1, n - 1 の大きい方で分子を割るという事前の式変形により `(m + n - 2) * (m + n - 3) * ... * (n - 1) / (n - 1)!` (m - 1が大きい場合)のように桁数をある程度抑えて計算できる。 | ||
|
|
||
| 時間計算量は O(m + n)、空間計算量は O(1) (整数がデカすぎる場合には確証が持てないが、あまり大きくなければこれでいいと思う) | ||
|
|
||
| ### 方法2(step1.py) | ||
|
|
||
| ↑のような計算ではない解き方だとすると? | ||
|
|
||
| 各マス目に対して、そこまでの行き方を左上から順にマス目に書き込んでいけばよい。 | ||
| ただし、あるマス目への行き方の数は、`そのマスの左のマスまでの行き方 + そのマスの上のマスまでの行き方` である。 | ||
|
|
||
| このやり方だと、計算過程で出てくる数字が答えより必ず小さくなるので桁数の心配は(そもそも答えが大きすぎるとき以外は)しなくて良さそう。 | ||
| ただし、m \* n のグリッド全て(効率化しても対角線より上半分)に対してループを回すので時間計算量と空間計算量は O(m \* n) になる。 | ||
| 今回は 1 <= m, n <= 100 なのでかかっても数 ms 〜 数十 ms と予想できる。 | ||
|
|
||
| ## step2(整形&他の人のコードを読む) | ||
|
|
||
| 変数名: | ||
|
|
||
| - way より path の方がいいかも。 | ||
| - grid よりは num_paths とかの方が良さそう | ||
| - https://github.com/Fuminiton/LeetCode/pull/33#discussion_r2061953239 | ||
| - ただ個人的には、各マス目の path の数を num_paths と呼びたいのでその表には別の名前をつけたいかも。でもいい名前が思いつかないし長すぎても読みづらそうなのでこれを採用 | ||
| - index_xxx は単に xxx でいいかも | ||
|
|
||
| > 内側が掛け算で構わない、つまり、数字が同一オブジェクトであったとしても代入するときに immutable なので置き換えられるので構わないが、List は問題であるという認識をしておきましょう。 | ||
|
|
||
| https://discord.com/channels/1084280443945353267/1337642831824814192/1363923644635549928 | ||
|
|
||
| step1 で方法2を書いた際、初回でこのミスをしてしまった。 | ||
|
|
||
| ## step3(10分以内にさっとかける \* 3回) | ||
|
|
||
| 別オブジェクトを複数回作りたいときは `*` じゃなくて `for` で書く、と決めといた方が間違いづらいかも? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| from collections import deque | ||
|
|
||
|
|
||
| class Solution: | ||
| def uniquePaths(self, num_rows: int, num_columns: int) -> int: | ||
| grid = [[0] * num_columns for _ in range(num_rows)] | ||
| frontier = deque([(0, 0)]) | ||
| seen = set([(0, 0)]) | ||
| grid[0][0] = 1 | ||
| while frontier: | ||
| index_row, index_column = frontier.popleft() | ||
| num_ways = grid[index_row][index_column] | ||
| if index_row + 1 < num_rows: | ||
| grid[index_row + 1][index_column] += num_ways | ||
| if (index_row + 1, index_column) not in seen: | ||
| frontier.append((index_row + 1, index_column)) | ||
| seen.add((index_row + 1, index_column)) | ||
| if index_column + 1 < num_columns: | ||
| grid[index_row][index_column + 1] += num_ways | ||
| if (index_row, index_column + 1) not in seen: | ||
| frontier.append((index_row, index_column + 1)) | ||
| seen.add((index_row, index_column + 1)) | ||
|
|
||
| return grid[num_rows - 1][num_columns - 1] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| from collections import deque | ||
|
|
||
|
|
||
| class Solution: | ||
| def uniquePaths(self, num_rows: int, num_columns: int) -> int: | ||
| num_paths = [[0] * num_columns for _ in range(num_rows)] | ||
| frontier = deque([(0, 0)]) | ||
| seen = set([(0, 0)]) | ||
| num_paths[0][0] = 1 | ||
| while frontier: | ||
| row, column = frontier.popleft() | ||
| if row + 1 < num_rows: | ||
| num_paths[row + 1][column] += num_paths[row][column] | ||
| if (row + 1, column) not in seen: | ||
| frontier.append((row + 1, column)) | ||
| seen.add((row + 1, column)) | ||
| if column + 1 < num_columns: | ||
| num_paths[row][column + 1] += num_paths[row][column] | ||
| if (row, column + 1) not in seen: | ||
| frontier.append((row, column + 1)) | ||
| seen.add((row, column + 1)) | ||
|
|
||
| return num_paths[num_rows - 1][num_columns - 1] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| from collections import deque | ||
|
|
||
|
|
||
| class Solution: | ||
| def uniquePaths(self, num_rows: int, num_columns: int) -> int: | ||
| num_paths = [[0 for _ in range(num_columns)] for _ in range(num_rows)] | ||
| frontiers = deque([(0, 0)]) | ||
| seen = set([(0, 0)]) | ||
| num_paths[0][0] = 1 | ||
| while frontiers: | ||
| row, column = frontiers.popleft() | ||
| if row + 1 < num_rows: | ||
| num_paths[row + 1][column] += num_paths[row][column] | ||
| if (row + 1, column) not in seen: | ||
| frontiers.append((row + 1, column)) | ||
| seen.add((row + 1, column)) | ||
| if column + 1 < num_columns: | ||
| num_paths[row][column + 1] += num_paths[row][column] | ||
| if (row, column + 1) not in seen: | ||
| frontiers.append((row, column + 1)) | ||
| seen.add((row, column + 1)) | ||
|
|
||
| return num_paths[-1][-1] |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
row と column の 2 重ループで十分だと思いました。
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.
ありがとうございます。
おっしゃる通り単純な 2 重ループでも左→右、上→下の順番が守られるのでそれで十分ですね。気づいていませんでした。