算法小知识-----10.20----- 第K个语法符号

54 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第23天,点击查看活动详情

疯狂星期四,整一道题迎接快乐周五

第K个语法符号

该题出自力扣的779题 —— 第K个语法符号【中等题】

审题

我们构建了一个包含 n 行( 索引从 1  开始 )的表。首先在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。 例如,对于 n = 3 ,第 1 行是 0 ,第 2 行是 01 ,第3行是 0110 。 给定行数 n 和序数 k,返回第 n 行中第 k 个字符。( k 从索引 1 开始)

  • 该题是中等题,题意很简短,但是确实是有点意思,因为还需要掌握一定规律
  • 题意就是给出两个数值,变量n就是代表行数,下标从1开始,变量K代表,第n行的第k个字符,最终就是要返回k个字符。
    • 因此相对的业务规则就是:第一行恒定的是0,第二行会从前一行的字符裂变
    • 1会裂变为10
    • 0会裂变为01
  • 那么解题思路就迎刃而解了,如果是暴力解法,那么由于最大是30行,最多的字符会超出界限
  • 解析一下该题,其实拿到当前的第K个值,那么就直接可以倒推,每两个一组,往上推直到第1行
    • 一开始的时候可以想出倒推,但是路子走歪了,想要记录位置,倒推后再正推剪枝回到原位置,但是发现行不通
    • 然后利用假设法,判定当前值为1,开始倒推,推到第1行的时候,因为第一行恒定为0,如果推断结果不为0,那么证明假设失败,返回相反值即可

编码

class Solution {
    public int kthGrammar(int n, int k) {
        if (k == 1)return 0;
        //假设是1
        boolean flag = true;
        while (n != 1){
            if (k % 2 == 0){
                k = k >> 1;
                flag = !flag;
            }else {
                k = (k + 1) >> 1;
            }
            n--;
        }
        return !flag?1:0;
    }
}

image.png