-
Notifications
You must be signed in to change notification settings - Fork 0
779. K-th Symbol in Grammar #48
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,153 @@ | ||
| # Step1 | ||
|
|
||
| かかった時間:15min | ||
|
|
||
| 計算量: | ||
|
|
||
| 時間計算量:O(n) | ||
|
|
||
| 空間計算量:O(n) | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| row_len = 2 ** (n - 1) | ||
| assert k <= row_len | ||
| if row_len == 1: | ||
| return 0 | ||
|
|
||
| if k <= row_len // 2: | ||
| return self.kthGrammar(n-1, k) | ||
| else: | ||
| return 1 - self.kthGrammar(n-1, k - row_len // 2) | ||
| ``` | ||
| 思考ログ: | ||
| - row(t)とrow(t+1)の関係性について | ||
| - row(t+1) = row(t) + row(t)^c | ||
| - s^cはsを反転させたものとする | ||
| - 上記を踏まえると、len(row(t+1)) = 2*len(row(t))に注意して | ||
| - k <= len(row(t))なら、row(t+1)のkは、row(t)のkと同じ | ||
| - k > len(row(t))なら、row(t+1)のkは、row(t)のk-len(row(t))を反転させたものと同じ | ||
| - ところでこの関係性ってtrivialなものなのか?? | ||
|
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. 観察すれば思いつきやすいですが、意外と自明ではないですよね |
||
| - 不安になって帰納法で確認したが、なんか考え方が不自然なのかしら | ||
|
|
||
| # Step2 | ||
|
|
||
| 講師役目線でのセルフツッコミポイント: | ||
|
|
||
| 参考にした過去ログなど: | ||
| - https://github.com/hroc135/leetcode/pull/44 | ||
| - 二分木は頭にあってもよかった | ||
| - bits.OnesCountの内部実装 | ||
| - popcnt | ||
| - SWAR Algorithm | ||
| - https://github.com/olsen-blue/Arai60/pull/47 | ||
| - 2分木を考えてkの偶奇で親の値と同じになるかを判定 | ||
| - https://github.com/olsen-blue/Arai60/pull/47/files#r2002307405 | ||
| - これは思いつかないが知っておこう | ||
|
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. 思いつかないようなものでも、考え方を聞いて、(あまり時間をかけずに咀嚼して)選択肢の一つとして引き出しにしまっておくのは大事だと思いました。 |
||
| - https://github.com/Ryotaro25/leetcode_first60/pull/49 | ||
| - https://github.com/Ryotaro25/leetcode_first60/pull/49/files#r1894794397 | ||
| - https://github.com/Ryotaro25/leetcode_first60/pull/49/files#r1894838721 | ||
| - Brian Kernighan's Algorithmあたりの話? | ||
| - https://github.com/Yoshiki-Iwasa/Arai60/pull/39 | ||
| - https://github.com/yukik8/leetcode/commit/a0e14f3fbe34720d13fcb61916c99d2a424b7bc6 | ||
| - https://github.com/nittoco/leetcode/pull/29 | ||
| - bitcount | ||
| - 初手コレの人もいるのか | ||
|
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. こんなことやるんですね。 子供がその気になったら面白そうなので自分もやってみようかなと思いました。 |
||
| - https://github.com/nittoco/leetcode/pull/29/files#r1685749723 | ||
| - https://github.com/fhiyo/leetcode/pull/47 | ||
| - nではなくkを削っていってもいいのか | ||
| - https://github.com/goto-untrapped/Arai60/pull/26 | ||
| - https://github.com/SuperHotDogCat/coding-interview/pull/26 | ||
| - https://github.com/Mike0121/LeetCode/pull/18 | ||
| - https://github.com/Mike0121/LeetCode/pull/18/files#r1613819411 | ||
| - nではなくkを追う | ||
| - https://docs.python.org/ja/3/library/stdtypes.html#int.bit_count | ||
| - https://github.com/shining-ai/leetcode/pull/46 | ||
| - https://github.com/shining-ai/leetcode/pull/46/files#r1557731428 | ||
| - int.bit_count() | ||
| > 整数の絶対値の二進数表現における 1 の数 | ||
| - https://github.com/hayashi-ay/leetcode/pull/46 | ||
|
|
||
| 2分木(再帰) | ||
| ```python | ||
| class Solution: | ||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| if k == 1: | ||
| return 0 | ||
|
|
||
| if k % 2: | ||
| return self.kthGrammar(n - 1, (k + 1) // 2) | ||
| else: | ||
| return 1 - self.kthGrammar(n - 1, (k + 1) // 2) | ||
|
Comment on lines
+75
to
+82
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. kに1引いて0-indexedから考えて行った方が個人的にわかりやすく感じます。
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. nittocoさんの解法の感じですよね。 そもそもkを弄る必要がある時点であまりこの解法は想定されていないのかもしれませんね。 |
||
| ``` | ||
| 思考ログ: | ||
| - 各symbolを二分木のノードとして捉えて | ||
| - 0 | ||
| - 01 | ||
| - 0110 | ||
| - 01101001 | ||
| - kの偶奇と子ノードの対応は | ||
| - kが奇数:左の子 | ||
| - kが偶数:右の子 | ||
| - 右の子からその親に辿る時にsymbolが反転(0<->1)することに注意すると | ||
| - kが偶数 => 反転、kが奇数 => そのまま | ||
| - k -> (k + 1) // 2として一つ前の行のインデックスに更新 | ||
| - これを繰り返していけばいい | ||
| - 終了条件をnではなくkに変更してみた | ||
|
|
||
| 2分木(loop) | ||
| ```python | ||
| class Solution: | ||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| symbol = 0 | ||
| while k > 1: | ||
| if (k + 1) & 1: | ||
| symbol ^= 1 | ||
| k = (k + 1) >> 1 | ||
|
|
||
| return symbol | ||
| ``` | ||
| 思考ログ: | ||
| - 上の再帰をループに | ||
| - kを0-indexedにした方が綺麗に書けるが、kの意味を変えたくなかったのでこのままで実装 | ||
|
|
||
| pop count | ||
| ```python | ||
| class Solution: | ||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| return int.bit_count(k-1) % 2 | ||
| ``` | ||
| 思考ログ: | ||
| - 2分木をもう少し考察すると、k-1のbit-countをすればいいことが分かる | ||
| - kを0-indexedにする(k = k-1と置き直す) | ||
| - 最下位ビットの偶奇チェック、0-indexedの場合、奇数なら反転することに注意 | ||
| - 1右にシフトさせて(前の行のインデックスに変換して)同様のチェックを根まで繰り返す | ||
| - ビットの数=反転の数 | ||
| - 反転が偶数回なら0、奇数回なら1を返せばいい | ||
|
|
||
| # Step3 | ||
|
|
||
| かかった時間:2min | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| if k == 1: | ||
| return 0 | ||
|
|
||
| if k % 2: | ||
|
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 k % 2 == 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. 反転する処理をメインにした方が良いという意図でしょうか? |
||
| return self.kthGrammar(n - 1, (k + 1) // 2) | ||
| else: | ||
| return 1 - self.kthGrammar(n - 1, (k + 1) // 2) | ||
| ``` | ||
| 思考ログ: | ||
| - 2分木を想起出来なかったので反省として | ||
| - ループか再帰かは個人的な好みで再帰の方が分かりやすかったため | ||
|
|
||
| # Step4 | ||
|
|
||
| ```python | ||
| ``` | ||
| 思考ログ: | ||
|
|
||
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.
-の両側にスペースを空けることをお勧めします。参考までにスタイルガイドへのリンクを貼ります。
https://peps.python.org/pep-0008/#whitespace-in-expressions-and-statements
https://google.github.io/styleguide/pyguide.html#s3.6-whitespace
ただし、上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。
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.
ご指摘ありがとうございます。
意図せずこの書き方になっていました。
最後のコメントも大事ですね。結構原理主義的になってしまいがちなので、チームで合意することを最優先にして進めるように気をつけます。