第K个语法符号

第K个语法符号

题目来源:leetcode
在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。

给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始)

输入: N = 1, K = 1
输出: 0

输入: N = 2, K = 1
输出: 0

输入: N = 2, K = 2
输出: 1

输入: N = 4, K = 5
输出: 1

解释:
第一行: 0
第二行: 01
第三行: 0110
第四行: 01101001

注意:

N 的范围 [1, 30].
K 的范围 [1, 2^(N-1)].

方法一:

题解思路:
1、每一行的个数是2^(N-1);
2、拿第三行和第四行举例:第四行前一半的数和第三行相同,后一半的数等于第三行数取反所得。

代码:

 //    static int M(int N,int K)
        //{
        //    if (N==1)
        //    {
        //        return 0;
        //    }
        //    int t = Convert.ToInt32(Math.Pow(2, N - 2));//就是2的N-2次方
        //    if (K<=t)
        //    {
        //        return M(N - 1, K);
        //    }
        //    else
        //    {
        //        return M(N - 1, K - t) == 1 ? 0 : 1;
        //    }
        //}
        static void Main(string[] args)
        {               
            // Console.WriteLine("输入N");
            // int N = Convert.ToInt16(Console.ReadLine());
            // Console.WriteLine("输入K");
            // int K = Convert.ToInt16(Console.ReadLine());
            //Console.WriteLine( M(N, K));
        }

方法二:

思路分析:N的取值范围是 [1, 30],意味着K的取值可能达到230,这将是一个非常大的数,因此想构造出这个序列然后直接找出第K未是非常不现实的。首先我们来看一下这棵满二叉树排序序号结构

//序号
//              1
//          /        \   
//      1                2
//    /   \            /    \
//  1       2        3       4
// / \     /  \     /  \    / \ 
//1   2   3    4   5    6  7   8

不难发现一个规律:(K + 1) / 2是K的父节点所在的序号。
再来看一下01值的分布图

//01排列
//              0
//          /        \   
//      0                1
//    /   \            /    \
//  0       1        1       0
// / \     /  \     /  \    / \ 
//0   1   1    0   1    0  0   1

可以再得到一个规律,如果K是奇数,则K的状态与K的父节点的状态相同,否则K的状态与K的父节点状态相反。
所以我们先利用递归求得K的父节点,然后根据K的奇偶性求出K的值。

代码:

class Solution {
public:
    int kthGrammar(int N, int K) {
        if (N == 1){//第一层:树的根
            return 0;
        }
        //第一步:先求出当前K的父节点状态(注意bool值默认0是false,1是true)
        bool father = kthGrammar(N - 1, (K + 1) / 2);
        //第二步:根据K的奇偶性求出当前K的状态
        if (K % 2 == 1){
            return father;
        }
        else{
            return !father;
        }
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值