携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情
前言
小白算法比较菜,希望能激励我每日更新,从leetcode第一题开始,2022年目标300题,记录从0到1的全过程!!
1545. 找出第 N 个二进制字符串中的第 K 位
1545. 找出第 N 个二进制字符串中的第 K 位
给你两个正整数 n 和 k,二进制字符串 Sn 的形成规则如下:
S1 = "0"
当 i > 1 时,Si = Si-1 + "1" + reverse(invert(Si-1))
其中 + 表示串联操作,reverse(x) 返回反转 x 后得到的字符串,而 invert(x) 则会翻转 x 中的每一位(0 变为 1,而 1 变为 0)。
例如,符合上述描述的序列的前 4 个字符串依次是:
S1 = "0"
S2 = "011"
S3 = "0111001"
S4 = "011100110110001"
请你返回 Sn 的 第 k 位字符 ,题目数据保证 k 一定在 Sn 长度范围以内。
示例1
输入: n = 3, k = 1
输出: "0"
解释: S3 为 "0111001",其第 1 位为 "0" 。
示例2
输入: n = 4, k = 11
输出: "1"
解释: S4 为 "011100110110001",其第 11 位为 "1" 。
示例3
输入: n = 1, k = 1
输出: "0"
示例4
输入: n = 2, k = 3
输出: "1"
2.解析
这个题首先要理解他做了什么。
S1 = "0"
S2 = S1 + 1 + (S1取反)后反序 = 0 + 1 + 1 = 0 1 1
S3 = S2 + 1 + (S2取反)后反序 = 011 + 1 + (100)反序 = 011 + 1 + 001 = 011 1 001
S4 = S3 + 1 + (S3取反)后反序 = 0111001 + 1 + (1000110)反序 = 0111001 1 0110001
我们可以发现,除了S1,其余在加粗的2、4、8位上的都是1,而它的左右两边都是对称取反,那我们就从这下手。以S4为例,如果查询的k是第10位,那它的结果是第8+8-10=6位数的取反,因为第六位和第十位是以第八位镜像取反的。
第六位又是S3中4+4-6=2位的取反。
S3的第二位也是S2的第二位的取反。
S2的第二位是它的中间值,所以位1.
所以S3的第二位是0,S4的第六位是1,S4的第十位是0.
S1有1位数,S2有3位数,S3有7位数,S4有15位数,S5有31位数,Sn有2^n-1位数。k不能大于中间值。
2.1解法
class Solution {
public char findKthBit(int n, int k) {
if(k==1) return '0';
int temp = 1 << (n-1);
if(k < temp) {
return findKthBit(n - 1, k);
}else if (k==temp) {
return '1';
}else {
k = temp - k + temp;
return findKthBit(n-1,k) == '1' ? '0' :'1';
}
}
}
提交排名
3.结束
思路有一点绕,但是把这个数据的拼接,取反,反序的过程走几遍,就知道每一步是做了什么,就知道代码是如何逆向求解的了。