Skip to content

Commit c490190

Browse files
committed
feat: add solutions to lc problem: No.0779
No.0779.K-th Symbol in Grammar
1 parent f1c5079 commit c490190

File tree

6 files changed

+96
-22
lines changed

6 files changed

+96
-22
lines changed

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,39 @@ n = 5: 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
7777

7878
时间复杂度 $O(n)$,空间复杂度 $O(n)$。
7979

80+
**方法二:位运算 + 脑筋急转弯**
81+
82+
题目中索引从 $1$ 开始,我们将 $k$ 改成 $k-1$,将索引转换为从 $0$ 开始。在接下来的讨论中,索引均从 $0$ 开始。
83+
84+
仔细观察,一行中的第 $i$ 个字符,会在第 $2i$ 和第 $2i+1$ 个位置产生两个字符。
85+
86+
```
87+
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
88+
```
89+
90+
如果第 $i$ 个字符是 $0$,那么在位置 $2i$ 和 $2i+1$ 产生的字符分别是 $0$ 和 $1$;如果第 $i$ 个字符是 $1$,产生的字符是 $1$ 和 $0$。
91+
92+
```
93+
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
94+
^ * *
95+
```
96+
97+
```
98+
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
99+
^ * *
100+
```
101+
102+
可以发现,第 $2i$ (偶数位)个字符总是和第 $i$ 个字符相同,而第 $2i+1$ (奇数位)个字符是第 $i$ 个字符的反转。也就是说,奇数位上的字符总是发生了一次反转而来的。反转偶数次,字符不变;反转奇数次,相当于反转了一次。
103+
104+
因此,我们只需要看 $k$ 这个数字是否是奇数,若是,累计一次反转。然后将 $k$ 除以 $2$,继续判断,并累计反转次数,直至 $k$ 为 $0$。
105+
106+
最后判断反转的次数是否为奇数,是则答案为 $1$,否则为 $0$。
107+
108+
以上累计反转次数的过程,实际上等价于求 $k$ 的二进制表示中,有多少位是 $1$。
109+
110+
时间复杂度 $O(\log k)$,空间复杂度 $O(1)$。
111+
112+
80113
<!-- tabs:start -->
81114

82115
### **Python3**
@@ -93,6 +126,12 @@ class Solution:
93126
return self.kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1
94127
```
95128

129+
```python
130+
class Solution:
131+
def kthGrammar(self, n: int, k: int) -> int:
132+
return (k - 1).bit_count() & 1
133+
```
134+
96135
### **Java**
97136

98137
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -111,6 +150,15 @@ class Solution {
111150
}
112151
```
113152

153+
154+
```java
155+
class Solution {
156+
public int kthGrammar(int n, int k) {
157+
return Integer.bitCount(k - 1) & 1;
158+
}
159+
}
160+
```
161+
114162
### **C++**
115163

116164
```cpp
@@ -124,6 +172,15 @@ public:
124172
};
125173
```
126174
175+
```cpp
176+
class Solution {
177+
public:
178+
int kthGrammar(int n, int k) {
179+
return __builtin_popcount(k - 1) & 1;
180+
}
181+
};
182+
```
183+
127184
### **Go**
128185

129186
```go
@@ -138,6 +195,12 @@ func kthGrammar(n int, k int) int {
138195
}
139196
```
140197

198+
```go
199+
func kthGrammar(n int, k int) int {
200+
return bits.OnesCount(uint(k-1)) & 1
201+
}
202+
```
203+
141204
### **...**
142205

143206
```

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ class Solution:
6565
return self.kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1
6666
```
6767

68+
```python
69+
class Solution:
70+
def kthGrammar(self, n: int, k: int) -> int:
71+
return (k - 1).bit_count() & 1
72+
```
73+
6874
### **Java**
6975

7076
```java
@@ -81,6 +87,14 @@ class Solution {
8187
}
8288
```
8389

90+
```java
91+
class Solution {
92+
public int kthGrammar(int n, int k) {
93+
return Integer.bitCount(k - 1) & 1;
94+
}
95+
}
96+
```
97+
8498
### **C++**
8599

86100
```cpp
@@ -94,6 +108,15 @@ public:
94108
};
95109
```
96110
111+
```cpp
112+
class Solution {
113+
public:
114+
int kthGrammar(int n, int k) {
115+
return __builtin_popcount(k - 1) & 1;
116+
}
117+
};
118+
```
119+
97120
### **Go**
98121

99122
```go
@@ -108,6 +131,12 @@ func kthGrammar(n int, k int) int {
108131
}
109132
```
110133

134+
```go
135+
func kthGrammar(n int, k int) int {
136+
return bits.OnesCount(uint(k-1)) & 1
137+
}
138+
```
139+
111140
### **...**
112141

113142
```
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
class Solution {
22
public:
33
int kthGrammar(int n, int k) {
4-
if (n == 1) return 0;
5-
if (k <= (1 << (n - 2))) return kthGrammar(n - 1, k);
6-
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
4+
return __builtin_popcount(k - 1) & 1;
75
}
86
};
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
11
func kthGrammar(n int, k int) int {
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
2+
return bits.OnesCount(uint(k-1)) & 1
93
}
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
class Solution {
22
public int kthGrammar(int n, int k) {
3-
if (n == 1) {
4-
return 0;
5-
}
6-
if (k <= (1 << (n - 2))) {
7-
return kthGrammar(n - 1, k);
8-
}
9-
return kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1;
3+
return Integer.bitCount(k - 1) & 1;
104
}
115
}
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
class Solution:
22
def kthGrammar(self, n: int, k: int) -> int:
3-
if n == 1:
4-
return 0
5-
if k <= (1 << (n - 2)):
6-
return self.kthGrammar(n - 1, k)
7-
return self.kthGrammar(n - 1, k - (1 << (n - 2))) ^ 1
3+
return (k - 1).bit_count() & 1

0 commit comments

Comments
 (0)