On the first row, we write a 0
. Now in every subsequent row, we look at the previous row and replace each occurrence of 0
with 01
, and each occurrence of 1
with 10
.
Given row N
and index K
, return the K
-th indexed symbol in row N
. (The values of K
are 1-indexed.) (1 indexed).
Examples: Input: N = 1, K = 1 Output: 0 Input: N = 2, K = 1 Output: 0 Input: N = 2, K = 2 Output: 1 Input: N = 4, K = 5 Output: 1 Explanation: row 1: 0 row 2: 01 row 3: 0110 row 4: 01101001
Note:
N
will be an integer in the range[1, 30]
.K
will be an integer in the range[1, 2^(N-1)]
.
第K个语法符号。
在第一行我们写上一个 0
。接下来的每一行,将前一行中的0
替换为01
,1
替换为10
。给定行数 N
和序数 K
,返回第 N
行中第 K
个字符。(K
从1开始)。
这道题属于数学/递归。我这里引用了一个帖子,如果你把这个替换的结果以一棵树的形式画出来,思路就比较好总结了。题目问的是找第 N 行的第 K 个数字。因为对于每一行来说,都是由他的上一行衍生出来的,所以递归函数写的时候也应该跟上一行有关,且第 N - 1 行的一个元素依次确定第 N 行的两个元素。并且我们可以分类K的奇偶和 (K+1) / 2 的取值得出递推关系。base case是当 N = 1 的时候,返回 0。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int kthGrammar(int N, int K) { 3 // base case, first row 4 if (N == 1) { 5 return 0; 6 } 7 8 // normal case 9 if (K % 2 == 0) { 10 if (kthGrammar(N - 1, K / 2) == 0) { 11 return 1; 12 } else { 13 return 0; 14 } 15 } else { 16 if (kthGrammar(N - 1, (K + 1) / 2) == 0) { 17 return 0; 18 } else { 19 return 1; 20 } 21 } 22 } 23 }
这里我再推荐另一种递归的做法,参见了这个帖子。
观察下面的规律,把每一行对半分开
1、0
2、0 | 1
3、01 | 10
4、0110 | 1001
5、01101001 | 10010110
6、0110100110010110 | 1001011001101001发现每一行的前半段就是上一行,后半段就是上一行的每个值反过来(0变1,1变0)
可以分为两种情况
如果K在前半段,所对应的值就是上一行的第K个值
如果K在后半段,可以先算出K相对于后半段的位置,然后找出上一行这个位置的值,把值反过来作者:zITy
链接:https://leetcode-cn.com/problems/k-th-symbol-in-grammar/solution/zhao-gui-lu-hou-ban-bu-fen-shi-qian-ban-wahnd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int kthGrammar(int N, int K) { 3 // base case 4 if (N == 1) { 5 return 0; 6 } 7 8 // normal case 9 int len = (int) Math.pow(2, N - 1); 10 if (K > len / 2) { 11 int val = kthGrammar(N - 1, K - len / 2); 12 return val == 1 ? 0 : 1; 13 } else { 14 return kthGrammar(N - 1, K); 15 } 16 } 17 }