From 880769728301d669071ebf3c3ce7335b3902bf1a Mon Sep 17 00:00:00 2001 From: fuga-98 <134851906+fuga-98@users.noreply.github.com> Date: Thu, 15 May 2025 11:53:28 +0900 Subject: [PATCH] Create 779. K-th Symbol in Grammar.md https://leetcode.com/problems/k-th-symbol-in-grammar/description/ --- 779. K-th Symbol in Grammar.md | 131 +++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 779. K-th Symbol in Grammar.md diff --git a/779. K-th Symbol in Grammar.md b/779. K-th Symbol in Grammar.md new file mode 100644 index 0000000..4edd9da --- /dev/null +++ b/779. K-th Symbol in Grammar.md @@ -0,0 +1,131 @@ +# 進め方 + +Step1 : 問題を解く。 + +Step2 : 他の人のPRを参照し、コメントする。 + +Step3 : 3回続けてエラーが出ないように書く。ドキュメントを参照する。 + +# 実践 + +## Step1 + +### 思考ログ + +入力が小さければ愚直にやってもいけそう。 + +O(2 ** n)なのでn=30だととても厳しい。 + +2の20乗が100万くらいなのでPythonだと2**10秒程度かかる + +全く思いつかないですね + +## Step2 + +### 同じ問題を解いた人のプルリクを見る + +https://github.com/olsen-blue/Arai60/pull/47 + +- この問題もっとマクロな話をするとビットカウントの偶奇になっていますよ。二分木を考えて、右に行くとビットが反転して、左に行くとしないということですね。 +- 「ある行は一つ前の行をコピーしてから反転させたものをくっつけた形になっている。」 +- なるほど、法則性があったのか。 + +0 + +01 + +0110 + +01101001 + +なるほど、nを使わずに求められそう。 + +> kの値にどう結びつくのかイメージできずでしたが、k-1 の二進数表記はルートからの移動パターンなんですね。 +k=5 (k-1=4, 二進数 100)だと、右(1)->左(0)->左(0)ですね。なので、k-1のビットを数えて偶奇を調べれば良いんですね。 +> + +なるほど + +bitと二分木が繋がるのすごい。 + +```python +class Solution: + def kthGrammar(self, n: int, k: int) -> int: + return (k - 1).bit_count() & 1 +``` + +```python +class Solution: + def kthGrammar(self, n: int, k: int) -> int: + if n == 1: + return 0 + + return self.kthGrammar(n - 1, (k + 1) // 2) ^ (k % 2 == 0) +``` + +bit反転に1 - x を使うのとx ^ 1 どちらがよいのだろうか。 + +notはちょっと嫌だなという気持ちです。 + +https://github.com/TORUS0818/leetcode/pull/48/files + +- whileで書く。 +- これは確かに再帰のほうが分かりやすいかも + +```python +class Solution: + def kthGrammar(self, n: int, k: int) -> int: + result = 0 + + while n > 1: + n -= 1 + if k % 2 == 1: + k = (k + 1) // 2 + continue + result ^= 1 + k //= 2 + return result +``` + +https://github.com/hroc135/leetcode/pull/44/files + +- bitの内部実装を読んでいる。 +- Arai60が終わったら、毎日少しずつCpythonとかを読みたいなあ。 + +## Step3 + +### 3回連続で再現できるように + +bit演算マシマシ + +```python +class Solution: + def kthGrammar(self, n: int, k: int) -> int: + if n == 1: + return 0 + return self.kthGrammar(n - 1, (k + 1) // 2) ^ ((k & 1) ^ 1) +``` + +notを使ってみた + +```python +class Solution: + def kthGrammar(self, n: int, k: int) -> int: + if n == 1: + return 0 + result = self.kthGrammar(n-1, (k+1) // 2) + return result ^ (not k % 2) +``` + +これが一番わかりやすいかな + +```python +class Solution: + def kthGrammar(self, n: int, k: int) -> int: + if n == 1: + return 0 + result = self.kthGrammar(n-1, (k+1) // 2) + return result ^ (k % 2 == 0) +``` + +bit演算なぜか好きです