-
Notifications
You must be signed in to change notification settings - Fork 0
779. K-th Symbol in Grammar #10
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,59 @@ | ||
|
|
||
| ## step1: | ||
| 0 | ||
| 01 | ||
| 0110 | ||
| 01101001 | ||
| 4th rowまでどう形成されるかを表してみた。4th rowの3番目の数に注視してみると、3rd rowの2番目が1だったため4th rowの3, 4番目の数が10となっている。このように、nth rowのk番目の数はn-1番目のrowの(k + 1)//2番目の数から派生する。もしn-1番目のrowの(k + 1)//2番目の数が0ならkは01のどちらかになり、0なら10のどちらかになる。もし01の場合はkが奇数の場合は0, 偶数の場合は1である。10の場合はkが奇数なら1, 偶数なら0となる。これをコードにすると以下のようになる。 | ||
| ### code | ||
| ```python | ||
| class Solution: | ||
| # 0 | ||
| # 01 | ||
| # 0110 | ||
| # 01101001 | ||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| if n == 1: | ||
| return 0 | ||
| previous_val = self.kthGrammar(n - 1, (k + 1)//2) | ||
| if previous_val == 0: | ||
| #01 | ||
| return (k - 1)%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. 演算子の周りのスペースの空け方に一貫性がないのが気になりました。
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. +, -は前後にスペースを入れて、/, *は全部詰めてたんですけどPEP8的には優先される演算子に関してはスペースなし、優先されない演算子にはスペースを開けるように書かれてました。 なのでこの場合は(k+1) // 2, return 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. 念のため、これは全部開けても全部空けなくてもいいが、優先度の高いところが空けたらそこよりも優先度の低いところは空けろということかと思います。 |
||
| else: | ||
| #10 | ||
| return 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.
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. それだと文字列を返していますね。
|
||
| ``` | ||
| 他の人のコードを見てみる。 | ||
| https://github.com/kitano-kazuki/leetcode/pull/47/changes | ||
| n行k番目のシンボルはn-1行{(k+1)//2}番目をもとに決まり、kが奇数の時はn-1行目のシンボルと一緒、kが偶数の時はn-1行目のシンボルと反対するという性質をもとにn=nからn=1までloopで辿り、n=1の0と一緒か反対かを求めて返している。これでもいいと思うが、k番目の数というのをcolで表していて個人的にこれはn×mの二次元配列に使うべきで、今回のようにnの数によって長さが変わる文字列に対してインデックスをcolと名付けると誤解を生じやすいと感じた。kでいい気がする。 | ||
|
Comment on lines
+26
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. コードとは関係ない & もし意図してのことでしたら恐縮ですが,markdownでは2行分改行しないとレンダリング時に改行されません. |
||
|
|
||
| https://github.com/hayashi-ay/leetcode/pull/46/changes | ||
| この人は最初に入力サイズを見て制約を考えていたので、自分も参考にして制約を考えてみる。1 <= n <= 30, 1 <= k <= 2^(n-1)ということで、愚直にnth rowまでの文字列を展開してk番目の文字を線形探索すると考えると、PythonのUTF-8文字列で '0' や '1' は 1 byteなので2^29byte≒1000^3/2=500MB。競プロでは250MBあたりがボーダーらしいので全ての文字を展開するのは現実的ではなさそう。線形探索も2^29≒10^9/2で、CPUが1秒に10^9回の単純演算を行うことができるのを考慮するとマックスで0.5秒で判断できる。これを考慮するとこの人がMemory Limit Exceedになったのが納得できる。 | ||
|
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のstrはUTF-8を使っていますか?
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://peps.python.org/pep-0393/ ChatGPTには 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.
strのk番目の文字を確認するのに線形探索が必要でしょうか?
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. 普通に文字列[k-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. もしUTF-8のようにvariable-length encodingだったら、確かに線形探索が必要でしたね。 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.
クロック数のことを指しているのなら、1GHzだと、かなり遅くないですかね? また、クロック数を直接Pythonの実行時間の見積もりに使うのは、飛躍がありそうに思いました。
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. 今回目安に10^9を持ってきましたが秒数を導き出すのは難しそうですね。最初の方針を思いつく段階ではオーダー記法のみに言及するようにします。 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の場合は 10^7steps / secでざっくり考えています。総計算ステップ数が10^9/2であれば50 sくらいでしょうか
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. 50sもかかるんですね...目安を教えてくださりありがとうございます🙏 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. ありがとうございます!10^6〜10^7/secで覚えておきます! |
||
|
|
||
| ## step2: | ||
| ### code | ||
| ```python | ||
| class Solution: | ||
|
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. この解法だと空間計算量がO(N)かかりますけど1 <= n <= 30なので特に問題はないと思います。nが1000を超えそうなあたりから再帰でなくループを検討するのが良さそうですね。 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から始めなくてもできますね。 |
||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| if n == 1: | ||
| return 0 | ||
| previous_val = self.kthGrammar(n - 1, (k + 1)//2) | ||
| if previous_val == 0: | ||
| return (k - 1)%2 | ||
| else: | ||
| return k%2 | ||
| ``` | ||
|
|
||
| ## step3: | ||
| ### code | ||
| ```python | ||
| class Solution: | ||
| def kthGrammar(self, n: int, k: int) -> int: | ||
| if n == 1: | ||
| return 0 | ||
| previous_val = self.kthGrammar(n - 1, (k + 1)//2) | ||
| if previous_val == 0: | ||
| return (k - 1)%2 | ||
| else: | ||
| return k%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.
個人的には「偶奇によってprivious_valを反転するか決める」という意味を反映させた
という書き方が好みです.
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.
これは流石に賛否両論ありそうですが,説明コメントを1行入れた上で
とかも1行でかけてシンプルかなと思います.