Skip to content

Commit 5fc7b7a

Browse files
LetMeFly666TisfyCopilot
authored
update: 添加问题“1545.找出第N个二进制字符串中的第K位”的代码和题解 (#1424)
* 1545: CE.cpp (#1423) - 悬垂引用 * 1545: AC.cpp (#1423) - AC,模拟,26.40%,22.84% * 1545: WA.cpp (#1423) * 1545: AC.cpp (#1423) - AC,dfs,100.00%,49.75% * 1545: AC.cpp (#1423) - AC,dfs_eaiser_to_understand,100.00%,83.76% * word: 4 days ago * 1545: WA.py (#1423) * 1545: WA.py (#1423) * 1545: AC.py (#1423) - AC,dfs_eaiser_to_understand,100.00%,57.04% * update: 添加问题“1545.找出第N个二进制字符串中的第K位”的代码和题解 (#1424) Signed-off-by: LetMeFly666 <Tisfy@qq.com> * 血月!狼人,嗷呜~ * fix: Apply suggestions from code review <summary> 标签缺少外层 <details> 开标签,导致折叠效果不会生效。建议补全为 <details><summary>例句</summary>...</details> 格式。 Co-authored-by: LetMeFly <Tisfy@qq.com> * Initial plan * better: Update Codes/1545-find-kth-bit-in-nth-binary-string_dfs.cpp * Rename files: fix spelling typo eaiserToUnderstand → easierToUnderstand Co-authored-by: LetMeFly666 <56995506+LetMeFly666@users.noreply.github.com> --------- Signed-off-by: LetMeFly666 <Tisfy@qq.com> Co-authored-by: Tisfy <Tisfy@foxmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 70bd60e commit 5fc7b7a

8 files changed

Lines changed: 376 additions & 1 deletion
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2026-03-03 09:03:20
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2026-03-03 09:14:52
6+
*/
7+
#if defined(_WIN32) || defined(__APPLE__)
8+
#include "_[1,2]toVector.h"
9+
#endif
10+
11+
class Solution {
12+
private:
13+
void invert(string& s) {
14+
for (char& c : s) {
15+
c = c == '0' ? '1' : '0';
16+
}
17+
}
18+
19+
string next(string& now) {
20+
string ans = now + '1';
21+
invert(now);
22+
reverse(now.begin(), now.end());
23+
ans += now;
24+
return ans;
25+
}
26+
public:
27+
char findKthBit(int n, int k) {
28+
string now = "0";
29+
for (int i = 2; i <= n; i++) {
30+
now = next(now);
31+
}
32+
return now[k - 1];
33+
}
34+
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2026-03-03 09:14:56
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2026-03-03 09:28:21
6+
*/
7+
#if defined(_WIN32) || defined(__APPLE__)
8+
#include "_[1,2]toVector.h"
9+
#endif
10+
11+
/*
12+
n1 = 1
13+
n2 = 2 * n1 + 1
14+
n3 = 2 * n2 + 1
15+
...
16+
求n的通项公式
17+
n_k = 2^k - 1
18+
*/
19+
class Solution {
20+
public:
21+
char findKthBit(int n, int k, bool invert=false) {
22+
if (n == 1) {
23+
return invert ? '1' : '0';
24+
}
25+
int len = (1 << n) - 1;
26+
int half_len = len >> 1;
27+
if (k == half_len + 1) {
28+
return invert ? '0' : '1';
29+
} else if (k <= half_len) {
30+
return findKthBit(n - 1, k, invert);
31+
} else {
32+
return findKthBit(n - 1, len - k + 1, !invert); // n = 2, k = 3 -> len = 3, half_len = 1, next_k = 1
33+
}
34+
}
35+
};
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* @Author: LetMeFly
3+
* @Date: 2026-03-03 09:14:56
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2026-03-03 09:39:20
6+
*/
7+
#if defined(_WIN32) || defined(__APPLE__)
8+
#include "_[1,2]toVector.h"
9+
#endif
10+
11+
/*
12+
n1 = 1
13+
n2 = 2 * n1 + 1
14+
n3 = 2 * n2 + 1
15+
...
16+
求n的通项公式
17+
n_k = 2^k - 1
18+
*/
19+
class Solution {
20+
private:
21+
inline char invert(char c) {
22+
return c == '0' ? '1' : '0';
23+
}
24+
public:
25+
char findKthBit(int n, int k) {
26+
if (n == 1) {
27+
return '0';
28+
}
29+
int len = (1 << n) - 1;
30+
int half_len = len >> 1;
31+
if (k == half_len + 1) {
32+
return '1';
33+
} else if (k <= half_len) {
34+
return findKthBit(n - 1, k);
35+
} else {
36+
return invert(findKthBit(n - 1, len - k + 1)); // n = 2, k = 3 -> len = 3, half_len = 1, next_k = 1
37+
}
38+
}
39+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'''
2+
Author: LetMeFly
3+
Date: 2026-03-03 20:11:50
4+
LastEditors: LetMeFly.xyz
5+
LastEditTime: 2026-03-03 20:16:16
6+
'''
7+
class Solution:
8+
def invert(self, n: str) -> str:
9+
return '1' if n == '0' else '0'
10+
11+
def findKthBit(self, n: int, k: int) -> str:
12+
if n == 1:
13+
return '0'
14+
len = (1 << n) - 1
15+
half = len >> 1
16+
if k == half + 1:
17+
return '1'
18+
elif k <= half:
19+
return self.findKthBit(n - 1, k)
20+
else:
21+
return self.invert(self.findKthBit(n - 1, len - k + 1))

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@
610610
|1535.找出数组游戏的赢家|中等|<a href="https://leetcode.cn/problems/find-the-winner-of-an-array-game/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2024/05/19/LeetCode%201535.%E6%89%BE%E5%87%BA%E6%95%B0%E7%BB%84%E6%B8%B8%E6%88%8F%E7%9A%84%E8%B5%A2%E5%AE%B6/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/139040126" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/find-the-winner-of-an-array-game/solutions/2782688/letmefly-1535zhao-chu-shu-zu-you-xi-de-y-ff3w/" target="_blank">LeetCode题解</a>|
611611
|1536.排布二进制网格的最少交换次数|中等|<a href="https://leetcode.cn/problems/minimum-swaps-to-arrange-a-binary-grid/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2026/03/02/LeetCode%201536.%E6%8E%92%E5%B8%83%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%BD%91%E6%A0%BC%E7%9A%84%E6%9C%80%E5%B0%91%E4%BA%A4%E6%8D%A2%E6%AC%A1%E6%95%B0/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/158569710" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/minimum-swaps-to-arrange-a-binary-grid/solutions/3911420/letmefly-1536pai-bu-er-jin-zhi-wang-ge-d-sobp/" target="_blank">LeetCode题解</a>|
612612
|1542.找出最长的超赞子字符串|困难|<a href="https://leetcode.cn/problems/find-longest-awesome-substring/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2024/05/20/LeetCode%201542.%E6%89%BE%E5%87%BA%E6%9C%80%E9%95%BF%E7%9A%84%E8%B6%85%E8%B5%9E%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/139077950" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/find-longest-awesome-substring/solutions/2784697/letmefly-1542zhao-chu-zui-chang-de-chao-16nco/" target="_blank">LeetCode题解</a>|
613+
|1545.找出第N个二进制字符串中的第K位|中等|<a href="https://leetcode.cn/problems/find-kth-bit-in-nth-binary-string/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2026/03/03/LeetCode%201545.%E6%89%BE%E5%87%BA%E7%AC%ACN%E4%B8%AA%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E7%AC%ACK%E4%BD%8D/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/158621541" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/find-kth-bit-in-nth-binary-string/solutions/3913171/letmefly-1545zhao-chu-di-n-ge-er-jin-zhi-5iuu/" target="_blank">LeetCode题解</a>|
613614
|1550.存在连续三个奇数的数组|简单|<a href="https://leetcode.cn/problems/three-consecutive-odds/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2025/05/11/LeetCode%201550.%E5%AD%98%E5%9C%A8%E8%BF%9E%E7%BB%AD%E4%B8%89%E4%B8%AA%E5%A5%87%E6%95%B0%E7%9A%84%E6%95%B0%E7%BB%84/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/147872651" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/three-consecutive-odds/solutions/3674069/letmefly-1550cun-zai-lian-xu-san-ge-qi-s-1mbl/" target="_blank">LeetCode题解</a>|
614615
|1552.两球之间的磁力|中等|<a href="https://leetcode.cn/problems/magnetic-force-between-two-balls/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2025/02/14/LeetCode%201552.%E4%B8%A4%E7%90%83%E4%B9%8B%E9%97%B4%E7%9A%84%E7%A3%81%E5%8A%9B/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/145629037" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/magnetic-force-between-two-balls/solutions/3074287/letmefly-1552liang-qiu-zhi-jian-de-ci-li-ptbu/" target="_blank">LeetCode题解</a>|
615616
|1572.矩阵对角线元素的和|简单|<a href="https://leetcode.cn/problems/matrix-diagonal-sum/" target="_blank">题目地址</a>|<a href="https://blog.letmefly.xyz/2023/08/11/LeetCode%201572.%E7%9F%A9%E9%98%B5%E5%AF%B9%E8%A7%92%E7%BA%BF%E5%85%83%E7%B4%A0%E7%9A%84%E5%92%8C/" target="_blank">题解地址</a>|<a href="https://letmefly.blog.csdn.net/article/details/132223172" target="_blank">CSDN题解</a>|<a href="https://leetcode.cn/problems/matrix-diagonal-sum/solutions/2382760/letmefly-1572ju-zhen-dui-jiao-xian-yuan-5qczr/" target="_blank">LeetCode题解</a>|
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
---
2+
title: 1545.找出第 N 个二进制字符串中的第 K 位:模拟 或 递归(数学)
3+
date: 2026-03-03 09:29:45
4+
tags: [题解, LeetCode, 中等, 递归, 字符串, 模拟, 数学]
5+
categories: [题解, LeetCode]
6+
---
7+
8+
# 【LetMeFly】1545.找出第 N 个二进制字符串中的第 K 位:模拟 或 递归(数学)
9+
10+
力扣题目链接:[https://leetcode.cn/problems/find-kth-bit-in-nth-binary-string/](https://leetcode.cn/problems/find-kth-bit-in-nth-binary-string/)
11+
12+
<p>给你两个正整数 <code>n</code> 和 <code>k</code>,二进制字符串  <code>S<sub>n</sub></code> 的形成规则如下:</p>
13+
14+
<ul>
15+
<li><code>S<sub>1</sub> = "0"</code></li>
16+
<li>当 <code>i > 1</code> 时,<code>S<sub>i</sub> = S<sub>i-1</sub> + "1" + reverse(invert(S<sub>i-1</sub>))</code></li>
17+
</ul>
18+
19+
<p>其中 <code>+</code> 表示串联操作,<code>reverse(x)</code> 返回反转 <code>x</code> 后得到的字符串,而 <code>invert(x)</code> 则会翻转 x 中的每一位(0 变为 1,而 1 变为 0)。</p>
20+
21+
<p>例如,符合上述描述的序列的前 4 个字符串依次是:</p>
22+
23+
<ul>
24+
<li><code>S<sub>1 </sub>= "0"</code></li>
25+
<li><code>S<sub>2 </sub>= "0<strong>1</strong>1"</code></li>
26+
<li><code>S<sub>3 </sub>= "011<strong>1</strong>001"</code></li>
27+
<li><code>S<sub>4</sub> = "0111001<strong>1</strong>0110001"</code></li>
28+
</ul>
29+
30+
<p>请你返回  <code>S<sub>n</sub></code> 的 <strong>第 <code>k</code> 位字符</strong> ,题目数据保证 <code>k</code> 一定在 <code>S<sub>n</sub></code> 长度范围以内。</p>
31+
32+
<p> </p>
33+
34+
<p><strong>示例 1:</strong></p>
35+
36+
<pre>
37+
<strong>输入:</strong>n = 3, k = 1
38+
<strong>输出:</strong>"0"
39+
<strong>解释:</strong>S<sub>3</sub> 为 "<strong>0</strong>111001",其第 1 位为 "0" 。
40+
</pre>
41+
42+
<p><strong>示例 2:</strong></p>
43+
44+
<pre>
45+
<strong>输入:</strong>n = 4, k = 11
46+
<strong>输出:</strong>"1"
47+
<strong>解释:</strong>S<sub>4</sub> 为 "0111001101<strong>1</strong>0001",其第 11 位为 "1" 。
48+
</pre>
49+
50+
<p><strong>示例 3:</strong></p>
51+
52+
<pre>
53+
<strong>输入:</strong>n = 1, k = 1
54+
<strong>输出:</strong>"0"
55+
</pre>
56+
57+
<p><strong>示例 4:</strong></p>
58+
59+
<pre>
60+
<strong>输入:</strong>n = 2, k = 3
61+
<strong>输出:</strong>"1"
62+
</pre>
63+
64+
<p> </p>
65+
66+
<p><strong>提示:</strong></p>
67+
68+
<ul>
69+
<li><code>1 <= n <= 20</code></li>
70+
<li><code>1 <= k <= 2<sup>n</sup> - 1</code></li>
71+
</ul>
72+
73+
74+
# 解题方法
75+
76+
## 解题方法一:模拟
77+
78+
写一个函数,求当前字符串的下一个字符串,一直模拟$n-1$次`next`就好了。注意最终返回下标`k-1`
79+
80+
+ 时间复杂度$O(2^n)$
81+
+ 空间复杂度$O(2^n)$
82+
83+
### AC代码
84+
85+
#### C++
86+
87+
```cpp
88+
/*
89+
* @LastEditTime: 2026-03-03 09:14:52
90+
*/
91+
class Solution {
92+
private:
93+
void invert(string& s) {
94+
for (char& c : s) {
95+
c = c == '0' ? '1' : '0';
96+
}
97+
}
98+
99+
string next(string& now) {
100+
string ans = now + '1';
101+
invert(now);
102+
reverse(now.begin(), now.end());
103+
ans += now;
104+
return ans;
105+
}
106+
public:
107+
char findKthBit(int n, int k) {
108+
string now = "0";
109+
for (int i = 2; i <= n; i++) {
110+
now = next(now);
111+
}
112+
return now[k - 1];
113+
}
114+
};
115+
```
116+
117+
## 解题方法二:递归 + 数学
118+
119+
对于字符串长度:
120+
121+
```
122+
n1 = 1
123+
n2 = 2 * n1 + 1
124+
n3 = 2 * n2 + 1
125+
126+
...
127+
128+
n_k = ?
129+
```
130+
131+
答案是$n_k=2^k-1$,原因如下:
132+
133+
> $n_{k+1} = 2n_k + 1$
134+
>
135+
> 两边都加一:$n_{k+1} + 1 = 2n_k + 1 + 1 = 2(n_k + 1)$
136+
>
137+
> 令 $a_k = n_k + 1$,则:$a_{k+1} = 2 \cdot a_k$
138+
>
139+
> $a_k$是一个公比为2的等比数列,且初项$a_1=n_1+1=2$,所以$a_k=2^k$
140+
>
141+
> 由于$a_k = n_k + 1$,所以$n_k=a_k-1=2^k-1$。
142+
143+
那么`findKthBit`就可以依据字符串的长度(计算自$n$)计算出要找的$k$在字符串中的哪个位置了:
144+
145+
> 字符串长度为$2^n-1$(记为$len$),说明生成这个字符串的上一个字符串的长度为$\frac{len}{2}$(记为$half\_len$)。
146+
>
147+
> + 如果$k==half\_len+1$,则说明正好处在<code>S<sub>i</sub> = S<sub>i-1</sub> + "1" + reverse(invert(S<sub>i-1</sub>))</code>中间的`1`,直接返回`1`;
148+
> + 如果$k\leq half\_len$,则说明处在<code>S<sub>i-1</sub></code>部分,返回`findKthBit(n - 1, k)`;
149+
> + 否则,说明处在<code>reverse(invert(S<sub>i-1</sub>))</code>位置,$k$在$len$中是倒数第$len-k+1$个元素<span title="俺想出来的通俗易懂的解释哈哈哈">,</span>,返回`revert(findKthBit(n - 1, len - k + 1))`。
150+
151+
+ 时间复杂度$O(n)$
152+
+ 空间复杂度$O(n)$
153+
154+
### AC代码
155+
156+
#### C++
157+
158+
```cpp
159+
/*
160+
* @LastEditTime: 2026-03-03 09:39:20
161+
*/
162+
class Solution {
163+
private:
164+
inline char invert(char c) {
165+
return c == '0' ? '1' : '0';
166+
}
167+
public:
168+
char findKthBit(int n, int k) {
169+
if (n == 1) {
170+
return '0';
171+
}
172+
int len = (1 << n) - 1;
173+
int half_len = len >> 1;
174+
if (k == half_len + 1) {
175+
return '1';
176+
} else if (k <= half_len) {
177+
return findKthBit(n - 1, k);
178+
} else {
179+
return invert(findKthBit(n - 1, len - k + 1)); // n = 2, k = 3 -> len = 3, half_len = 1, next_k = 1
180+
}
181+
}
182+
};
183+
```
184+
185+
#### Python
186+
187+
```py
188+
'''
189+
LastEditTime: 2026-03-03 20:16:16
190+
'''
191+
class Solution:
192+
def invert(self, n: str) -> str:
193+
return '1' if n == '0' else '0'
194+
195+
def findKthBit(self, n: int, k: int) -> str:
196+
if n == 1:
197+
return '0'
198+
len = (1 << n) - 1
199+
half = len >> 1
200+
if k == half + 1:
201+
return '1'
202+
elif k <= half:
203+
return self.findKthBit(n - 1, k)
204+
else:
205+
return self.invert(self.findKthBit(n - 1, len - k + 1))
206+
```
207+
208+
#### C++
209+
210+
当然也可以:
211+
212+
```cpp
213+
/*
214+
* @LastEditTime: 2026-03-03 09:28:21
215+
*/
216+
class Solution {
217+
public:
218+
char findKthBit(int n, int k, bool invert=false) {
219+
if (n == 1) {
220+
return invert ? '1' : '0';
221+
}
222+
int len = (1 << n) - 1;
223+
int half_len = len >> 1;
224+
if (k == half_len + 1) {
225+
return invert ? '0' : '1';
226+
} else if (k <= half_len) {
227+
return findKthBit(n - 1, k, invert);
228+
} else {
229+
return findKthBit(n - 1, len - k + 1, 1 ^ invert); // n = 2, k = 3 -> len = 3, half_len = 1, next_k = 1
230+
}
231+
}
232+
};
233+
```
234+
235+
236+
> 同步发文于[CSDN](https://letmefly.blog.csdn.net/article/details/158621541)和我的[个人博客](https://blog.letmefly.xyz/),原创不易,转载经作者同意后请附上[原文链接](https://blog.letmefly.xyz/2026/03/03/LeetCode%201545.%E6%89%BE%E5%87%BA%E7%AC%ACN%E4%B8%AA%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E7%AC%ACK%E4%BD%8D/)哦~
237+
>
238+
> 千篇源码题解[已开源](https://github.com/LetMeFly666/LeetCode)

Solutions/Other-English-LearningNotes-SomeWords.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1842,7 +1842,7 @@ categories: [自用]
18421842
|detain|v. 扣押,留住,耽搁|
18431843
|||
18441844
|rod|n. 杆,枝|
1845-
|c/o|abbr. (用于投递给寄居人的信件上)由...转交|
1845+
|c/o|= care of<br/>abbr. (用于投递给寄居人的信件上)由...转交<details><summary>例句</summary>Please send the package to John Smith <font color="#28bea0">c/o</font> Green Hotel.<br/>请将包裹寄给约翰·史密斯,由格林酒店转交。</details>|
18461846
|||
18471847
|testimony|n. 证词,证言,证据,证明|
18481848
|treason|n. 危害国家罪,叛逆,通敌,背叛|

toSay.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<!--
2+
* @Author: LetMeFly
3+
* @Date: 2026-03-03 20:26:53
4+
* @LastEditors: LetMeFly.xyz
5+
* @LastEditTime: 2026-03-03 20:27:07
6+
-->
7+
血月!狼人,嗷呜~

0 commit comments

Comments
 (0)