Skip to content

Commit ab9837a

Browse files
authored
feat: add solutions to lc problem: No.0779 (#4105)
No.0779.K-th Symbol in Grammar
1 parent f795901 commit ab9837a

File tree

4 files changed

+138
-6
lines changed

4 files changed

+138
-6
lines changed

solution/0700-0799/0779.K-th Symbol in Grammar/README.md

+33-2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ tags:
4040
<pre>
4141
<strong>输入:</strong> n = 2, k = 1
4242
<strong>输出:</strong> 0
43-
<strong>解释:</strong>
44-
第一行: 0
43+
<strong>解释:</strong>
44+
第一行: 0
4545
第二行: <u>0</u>1
4646
</pre>
4747

@@ -148,6 +148,20 @@ func kthGrammar(n int, k int) int {
148148
}
149149
```
150150

151+
#### TypeScript
152+
153+
```ts
154+
function kthGrammar(n: number, k: number): number {
155+
if (n == 1) {
156+
return 0;
157+
}
158+
if (k <= 1 << (n - 2)) {
159+
return kthGrammar(n - 1, k);
160+
}
161+
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
162+
}
163+
```
164+
151165
<!-- tabs:end -->
152166

153167
<!-- solution:end -->
@@ -225,6 +239,23 @@ func kthGrammar(n int, k int) int {
225239
}
226240
```
227241

242+
#### TypeScript
243+
244+
```ts
245+
function kthGrammar(n: number, k: number): number {
246+
return bitCount(k - 1) & 1;
247+
}
248+
249+
function bitCount(i: number): number {
250+
i = i - ((i >>> 1) & 0x55555555);
251+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
252+
i = (i + (i >>> 4)) & 0x0f0f0f0f;
253+
i = i + (i >>> 8);
254+
i = i + (i >>> 16);
255+
return i & 0x3f;
256+
}
257+
```
258+
228259
<!-- tabs:end -->
229260

230261
<!-- solution:end -->

solution/0700-0799/0779.K-th Symbol in Grammar/README_EN.md

+84-4
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ tags:
4040
<pre>
4141
<strong>Input:</strong> n = 2, k = 1
4242
<strong>Output:</strong> 0
43-
<strong>Explanation:</strong>
43+
<strong>Explanation:</strong>
4444
row 1: 0
4545
row 2: <u>0</u>1
4646
</pre>
@@ -50,7 +50,7 @@ row 2: <u>0</u>1
5050
<pre>
5151
<strong>Input:</strong> n = 2, k = 2
5252
<strong>Output:</strong> 1
53-
<strong>Explanation:</strong>
53+
<strong>Explanation:</strong>
5454
row 1: 0
5555
row 2: 0<u>1</u>
5656
</pre>
@@ -69,7 +69,26 @@ row 2: 0<u>1</u>
6969

7070
<!-- solution:start -->
7171

72-
### Solution 1
72+
### Solution 1: Recursion
73+
74+
Let's first observe the pattern of the first few rows:
75+
76+
```
77+
n = 1: 0
78+
n = 2: 0 1
79+
n = 3: 0 1 1 0
80+
n = 4: 0 1 1 0 1 0 0 1
81+
n = 5: 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
82+
...
83+
```
84+
85+
We can see that the first half of each row is exactly the same as the previous row, and the second half is the inversion of the previous row. Note that "inversion" here means changing $0$ to $1$ and $1$ to $0$.
86+
87+
If $k$ is in the first half, then the $k$-th character is the same as the $k$-th character of the previous row, so we can directly recurse with $kthGrammar(n - 1, k)$.
88+
89+
If $k$ is in the second half, then the $k$-th character is the inversion of the $(k - 2^{n - 2})$-th character of the previous row, i.e., $kthGrammar(n - 1, k - 2^{n - 2}) \oplus 1$.
90+
91+
The time complexity is $O(n)$, and the space complexity is $O(n)$.
7392

7493
<!-- tabs:start -->
7594

@@ -128,13 +147,57 @@ func kthGrammar(n int, k int) int {
128147
}
129148
```
130149

150+
#### TypeScript
151+
152+
```ts
153+
function kthGrammar(n: number, k: number): number {
154+
if (n == 1) {
155+
return 0;
156+
}
157+
if (k <= 1 << (n - 2)) {
158+
return kthGrammar(n - 1, k);
159+
}
160+
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
161+
}
162+
```
163+
131164
<!-- tabs:end -->
132165

133166
<!-- solution:end -->
134167

135168
<!-- solution:start -->
136169

137-
### Solution 2
170+
### Solution 2: Bit Manipulation + Brain Teaser
171+
172+
In the problem, the index starts from $1$. We will change $k$ to $k-1$, converting the index to start from $0$. In the following discussion, all indices start from $0$.
173+
174+
Upon closer observation, the $i$-th character in a row generates two characters at positions $2i$ and $2i+1$ in the next row.
175+
176+
```
177+
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
178+
```
179+
180+
If the $i$-th character is $0$, then the characters generated at positions $2i$ and $2i+1$ are $0$ and $1$, respectively. If the $i$-th character is $1$, the generated characters are $1$ and $0$.
181+
182+
```
183+
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
184+
^ * *
185+
```
186+
187+
```
188+
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
189+
^ * *
190+
```
191+
192+
We can see that the character at position $2i$ (even index) is always the same as the character at position $i$, while the character at position $2i+1$ (odd index) is the inversion of the character at position $i$. In other words, characters at odd indices are always the result of one inversion. If the number of inversions is even, the character remains unchanged; if the number of inversions is odd, it is equivalent to one inversion.
193+
194+
Therefore, we only need to check whether $k$ is odd. If it is, we accumulate one inversion. Then, we divide $k$ by $2$ and continue to check, accumulating the number of inversions until $k$ becomes $0$.
195+
196+
Finally, we determine whether the number of inversions is odd. If it is, the answer is $1$; otherwise, it is $0$.
197+
198+
The process of accumulating the number of inversions is essentially equivalent to counting the number of $1$s in the binary representation of $k$.
199+
200+
The time complexity is $O(\log k)$, and the space complexity is $O(1)$.
138201

139202
<!-- tabs:start -->
140203

@@ -175,6 +238,23 @@ func kthGrammar(n int, k int) int {
175238
}
176239
```
177240

241+
#### TypeScript
242+
243+
```ts
244+
function kthGrammar(n: number, k: number): number {
245+
return bitCount(k - 1) & 1;
246+
}
247+
248+
function bitCount(i: number): number {
249+
i = i - ((i >>> 1) & 0x55555555);
250+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
251+
i = (i + (i >>> 4)) & 0x0f0f0f0f;
252+
i = i + (i >>> 8);
253+
i = i + (i >>> 16);
254+
return i & 0x3f;
255+
}
256+
```
257+
178258
<!-- tabs:end -->
179259

180260
<!-- solution:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function kthGrammar(n: number, k: number): number {
2+
if (n == 1) {
3+
return 0;
4+
}
5+
if (k <= 1 << (n - 2)) {
6+
return kthGrammar(n - 1, k);
7+
}
8+
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function kthGrammar(n: number, k: number): number {
2+
return bitCount(k - 1) & 1;
3+
}
4+
5+
function bitCount(i: number): number {
6+
i = i - ((i >>> 1) & 0x55555555);
7+
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
8+
i = (i + (i >>> 4)) & 0x0f0f0f0f;
9+
i = i + (i >>> 8);
10+
i = i + (i >>> 16);
11+
return i & 0x3f;
12+
}

0 commit comments

Comments
 (0)