5484. 找出第 N 个二进制字符串中的第 K 位

5484. 找出第 N 个二进制字符串中的第 K 位

题目描述:

给你两个正整数 nk,二进制字符串 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"

提示:

1 <= n <= 20
1 <= k <= 2n - 1

解题思路:

1)、按照题目的描述将字符串构造出来;

实现1(超时的方法):
     char findKthBit2(int n, int k) {
         vector<int> vCur(1,1) ;
         vector<int> vNext ;
         int i = 1 ;
         int tmp = vCur.size() ;
         while (i < n)
         {
             vNext = vCur ;
             reverse(vCur.begin() , vCur.end()) ;
             vNext.insert(vNext.end() , vCur.begin(), vCur.end()) ;
             if (tmp & 1) 
                vNext[tmp] ++ ;
             else
                vNext[tmp - 1] ++ ;
             vCur = vNext ;
         }
         i = 0 ;
         int sum = 0 ;
         for (int mm : vNext)
         {
             sum += mm
             if (sum > k)
             {
                 if (i & 1) return '1' ;
                 else return '0' ;
                 break ;
             }
             i ++ ;
         }
         return '0' ;
          
     }
实现2(超时的方法):
//翻转后逆转
    string reverseInvert(string  s)
    {
        string str = "" ;
        for (char c : s)
        {
            if (c == '0') str = '1' + str  ;
            else str = '0' +  str ;
        }
        return str ;
    }

    char findKthBit(int n, int k) {
        string sCur = "0" , sNext = "" ;
        int i = 1 ;
        while (i < n)
        {
            cout << sCur << endl ;
            sNext = sCur + "1" + reverseInvert(sCur);
            sCur = sNext ;
            i ++ ;
        }
        cout << sCur << endl ;
        return sCur[k] ;

    }
实现3(leecode 的 汪乐平 大佬)
class Solution {
    //string s[21],t[21];
public:
    char findKthBit(int n, int k) {
        string sCur = "0" , tCur = "1";
        string sNext , tNext ;
        int i = 1 ;
        while(i < n)
        {
            sNext = sCur;
            sNext += '1';
            sNext += tCur;
            tNext = sCur;
            tNext += '0';
            tNext += tCur;
            sCur = sNext ;
            tCur = tNext ;
            i ++ ;
        }
        return sCur[k-1];
    }
};

解题思路2(利用回文的特点)

1)、利用回文在相对于中间位置是对称的;
2)、因为相对于中心位置,右边的数据又是左边的逆转;('0' 换成 '1' , '1' 换成 '0');

代码实现:
class Solution {
    vector<int> kv ;
public:
//统计`Si` 的字符的个数;每一个`Si `都是呈现中心对称的。
    Solution()
    {
        kv.push_back(1) ;
        int tmp = 1 , i = 1 ;
        while (i ++ < 21)
        {
            tmp = (tmp << 1) + 1 ;
            kv.push_back(tmp) ;
        }
    }
    //change要计算翻转的次数
    char findKthBitChange(int k , int change) {
        if (k == 1) return (change & 1) ? '1' : '0' ;
        int i = 0 ;
        while (k > kv[i ++]) ;
        i -- ;
        if (k == kv[i] || k == kv[i - 1] + 1) return (change & 1)? '0' : '1' ;
        else
        {
            k = kv[i] - k + 1 ;
            change ++  ;
            //cout << change << endl ;
            return findKthBitChange(k , change) ;
        }

    }

    char findKthBit(int n, int k) {
        if (k == 1) return '0' ;
        else return findKthBitChange(k , 0) ;
    }
};
复杂度计算:

时间复杂度O(log n) ;
空间复杂度 O(1)因为 增加的是常数 10个额外的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值