[杨小白]_java_leetcode 1545. 找出第 N 个二进制字符串中的第 K 位

109 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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';
        }

    }
}

提交排名

image.png

3.结束

思路有一点绕,但是把这个数据的拼接,取反,反序的过程走几遍,就知道每一步是做了什么,就知道代码是如何逆向求解的了。