刷题的日常-第K个语法符号

89 阅读2分钟

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

刷题的日常-2022年10月20号

一天一题,保持脑子清爽

第K个语法符号

来自leetcode的 779 题,题意如下:

我们构建了一个包含 n 行(索引从 1 开始)的表。首先在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。

  • 例如,对于 n = 3 ,第 1 行是 0 ,第 2 行是 01 ,第3行是 0110 。

给定行数n和序数 k,返回第 n 行中第 k个字符。(k从索引 1 开始)

示例1:

输入: n = 1, k = 1
输出: 0
解释: 第一行:0

理解题意

通过题意,我们可以将信息整理如下:

  • 题目出两个值,一个是行数 n,另外一个是行中的位置k
  • 给出两个规则
    • 如果是 1,下一行用01替换
    • 如果是 0,下一行用10替换
  • 返回第n行中的第k个位置的数

做题思路

第一想法是直接用队列去模拟,直接开辟个队列,不断进行出栈替换,最终返回第k个位置的数即可。可惜超时了。所以不能用这个方法实现。
另外一个思路是找规律,观察每一行的数据可以发现,下一行的结果是 上一行的结果 和 其自身的结果取反 然后拼在一起。当前位置是上一行变换来的,当前位置如果可以被2整除,说明产生了翻转,否则不需要和上一行一致,最终返回翻转后的结果,步骤如下:

  • 开辟一个值记录结果
  • 循环行数n
  • 如果当前k能被整除,那么就进行翻转,否则保持不变
  • k要往上找到上一层变换的位置
  • 最终返回翻转结果

代码实现

代码实现如下:

public class Solution {
    public int kthGrammar(int n, int k) {
        int result = 0;
        while (n-- > 0) {
            if (k % 2 == 0) {
                result ^= 1;
            }
            k = (k + 1) / 2;
        }
        return result;
    }
}

image.png