-
Notifications
You must be signed in to change notification settings - Fork 0
62. Unique Paths #39
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?
62. Unique Paths #39
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,19 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| // (m - 1) + (n - 1) = m + n - 2 | ||
| return combination(m + n - 2, min(m - 1, n - 1)); | ||
| } | ||
|
|
||
| private: | ||
| int64_t combination(int64_t n, int64_t r) { | ||
| int64_t result = 1; | ||
|
|
||
| for (int64_t i = 1; i <= r; i++) { | ||
| result *= (n - i + 1); | ||
| result /= i; | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| // (m - 1) + (n - 1) = m + n - 2 | ||
| return combination(m + n - 2, min(m - 1, n - 1)); | ||
| } | ||
|
|
||
| private: | ||
| int combination(int n, int r) { | ||
| long long result = 1; | ||
|
|
||
| for (int i = 1; i <= r; i++) { | ||
| result = result * (n - i + 1) / i; | ||
|
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. result *= ... 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. たぶん 例) 7C3の場合
Step2
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. n- i + 1で別変数定義も一瞬思いましたが、やや過剰ですかね
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. @hayashi-ay @nittoco |
||
| } | ||
|
|
||
| return static_cast<int>(result); | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| // (m - 1) + (n - 1) = m + n - 2 | ||
| return combination(m + n - 2, min(m - 1, n - 1)); | ||
| } | ||
|
|
||
| private: | ||
| int combination(int n, int r) { | ||
| long long result = 1; | ||
|
|
||
| for (int i = 1; i <= r; i++) { | ||
| result *= (n - i + 1) / i; | ||
| } | ||
|
|
||
| return static_cast<int>(result); | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| ## ステップ1 | ||
| 問題を見て思いついたのは | ||
| (m + n)!/m!n!の公式を使う解法と1マスごとに、ロボットが何パターンで進むことができたのか記録する方法。 | ||
| 今回は後者の方法で行う。右端に辿り着いた時点でのパターン数が解答になる。 | ||
|
|
||
| 時間計算量O(m n) | ||
| 空間計算量O(m n) | ||
|
|
||
| ## ステップ2 | ||
| i jを使うかrow colを使うかは好みの問題か | ||
| 空間計算量を抑えることはできる | ||
|
|
||
| ## 参考にした他の方の解法 | ||
| 基本的は方針は同じ | ||
| ~~数学的な解き方でも解いてみる。C++に階乗やコンビネーションのライブラリはなさそう。~~ | ||
| 数学的な解き方でも解いてみる。C++に階乗やコンビネーションの標準ライブラリはなさそう。 | ||
| https://github.com/Yoshiki-Iwasa/Arai60/pull/47 | ||
| combitation.cppに実装 | ||
| 扱う数字の大きさを抑える方法が分からなかったのでChat GPTに相談 | ||
|
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. Python だと標準で、Java だと BigInteger など多倍長整数を扱うことが標準でできるのですが、C++ はなかったと思います。おそらく Boost を使うなどになりますね。
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. @oda 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. 多倍長整数クラスは一度実装してみても良いかもしれません。 |
||
| combinationの第二引数には可能な限り小さい数値を渡すためにminを用いる | ||
| →たまたまLeetCodeのテストケースで通っただけのような気がする | ||
|
|
||
| 行単位もしくは列単位でパターン数を記録することで空間計算量をO(m) もしくはO(n)に抑えることができる | ||
| ただ、コード面接でこれは思いつけそうにない | ||
| https://github.com/fhiyo/leetcode/pull/34 | ||
| step4.cppに実装(写経) | ||
|
|
||
| ## Discordなど | ||
|
|
||
| ## 多倍長整数クラス | ||
| 64bitより長い数値を扱う計算全般を広義の多倍長(multiple precision)計算 | ||
|
|
||
| https://na-inet.jp/weblog2/2018/03/22/%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82%E3%80%8C%E5%A4%9A%E5%80%8D%E9%95%B7%E3%80%8D%E3%81%A3%E3%81%A6%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E6%84%8F%E5%91%B3%EF%BC%9F/ | ||
|
|
||
| https://zenn.dev/herumi/articles/bitint-01-cpp | ||
|
|
||
| Boost | ||
| https://ja.wikipedia.org/wiki/Boost_C%2B%2B%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA | ||
| cpp_int.hpp | ||
| https://github.com/boostorg/multiprecision/blob/develop/include/boost/multiprecision/cpp_int.hpp | ||
|
|
||
| 実装は難しかったので一周してから戻ってくる | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int row, int col) { | ||
| if (row == 1 || col == 1) { | ||
| return 1; | ||
| } | ||
| return uniquePaths(row - 1, col) + uniquePaths(row, col - 1); | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| vector<vector<int>> num_paths(m, vector<int>(n, 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. 後から上書きするから問題ないとして、とりあえず全部に 1 を入れておくのはあまり行儀が良くない(読む人を混乱させる)ようには思います。
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. Step5も結局コメントで補足を入れているので、個人的にはStep1の解法にコメントを足すだけでも良いのかなとも思いました。 |
||
|
|
||
| for (int i = 1; i < m; i++) { | ||
| for (int j = 1; j < n; j++) { | ||
| num_paths[i][j] = num_paths[i - 1][j] + num_paths[i][j - 1]; | ||
| } | ||
| } | ||
|
|
||
| return num_paths[m - 1][n - 1]; | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| vector<vector<int>> num_paths(m, vector<int>(n, 1)); | ||
|
|
||
| for (int i = 1; i < m; i++) { | ||
| for (int j = 1; j < n; j++) { | ||
| num_paths[i][j] = num_paths[i - 1][j] + num_paths[i][j - 1]; | ||
| } | ||
| } | ||
|
|
||
| return num_paths[m - 1][n - 1]; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| vector<vector<int>> num_paths(m, vector<int>(n, 1)); | ||
| for (int i = 1; i < m; i++) { | ||
| for (int j = 1; j < n; j++) { | ||
| num_paths[i][j] = num_paths[i - 1][j] + num_paths[i][j - 1]; | ||
| } | ||
| } | ||
|
|
||
| return num_paths[m - 1][n - 1]; | ||
| } | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| // m と n を比較して、n の方が大きい場合、m と n を交換 | ||
| if (m < n) { | ||
| swap(m, n); | ||
| } | ||
|
|
||
| vector<int> num_paths(n, 1); | ||
|
|
||
| // m - 1 回ループで行を更新 | ||
| for (int i = 1; i < m; i++) { | ||
| for (int j = 1; j < n; j++) { | ||
| // 左と上からの経路数を足す | ||
| num_paths[j] += num_paths[j - 1]; | ||
| } | ||
| } | ||
|
|
||
| // 最後のセルのパス数を返す | ||
| return num_paths[n - 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. 最後の要素を返すのであれば、 num_paths.back() のほうが分かりやすいと思います。 |
||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Solution { | ||
| public: | ||
| int uniquePaths(int m, int n) { | ||
| vector<vector<int>> num_paths(m, vector<int>(n)); | ||
| // 到達まで1パターンの部分を初期化 | ||
| for (int i = 0; i < m; i++) { | ||
| num_paths[i][0] = 1; | ||
| } | ||
| for (int j = 0; j < n; j++) { | ||
| num_paths[0][j] = 1; | ||
| } | ||
|
|
||
| for (int i = 1; i < m; i++) { | ||
| for (int j = 1; j < n; j++) { | ||
| num_paths[i][j] = num_paths[i - 1][j] + num_paths[i][j - 1]; | ||
| } | ||
| } | ||
|
|
||
| return num_paths[m - 1][n - 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.
long long
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.
@liquo-rice
早速の確認ありがとうございます。
処理はlong longで行っておりますが返却時にstatic_castを用いてint型にしております。
関数内でキャストはすべきでないですか?
Uh oh!
There was an error while loading. Please reload this page.
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.
intが必要な場面ならば、implicitにintにキャストされませんか?(おそらく警告が出ますかね。)仮にintで収まらない値を返すときはどうしたら良さそうですか?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.
上のuniquePathsでキャストした方が良さそうな気がします。
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.
自分なら int64_t を使うのですが、明示的な理由はありません。強いて言えば、メモリモデルによらずビット数が決まっているからでしょうか…。