题目
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)].
答题
思路一
数组思路,每行数组的大小为上一数组大小的2倍。通过递归获得第 N
行的数组,然后取出索引为 K
的值
public int kthGrammar(int N, int K) {
int[] array = count(new int[] { 0 }, N, 0);
return array[K - 1];
}
public int[] count(int[] array, int N, int count) {
if (count + 1 == N) {
return array;
}
int size = array.length * 2;
int[] temp = new int[size];
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
int val = array[i];
if (val == 0) {
temp[i * 2] = 0;
temp[i * 2 + 1] = 1;
} else {
temp[i * 2] = 1;
temp[i * 2 + 1] = 0;
}
}
return count(temp, N, ++count);
}
思路二
思路一中会不断的创建数组,所以不是一个好的方法。
row 1: 0
row 2: 01
row 3: 01 10
row 4: 0110 1001
row 5: 01101001 10010110
通过观察,我们会发现第5行前半截就是第4行,后半截需要重新生成,以此类推。并且第N行的数组大小为 2^(n-1) 。所以我们可以提前生成好第N行的数组,而不是每行创建一个数组。
public int kthGrammar(int N, int K) {
int CAPACITY = (int) Math.pow(2, N - 1);
ArrayList<Integer> list = new ArrayList<Integer>(CAPACITY);
list.add(0);
count(list, N, 0);
System.out.println(list);
return list.get(K - 1);
}
public List<Integer> count(List<Integer> list, int N, int count) {
if (count + 1 == N) {
return list;
}
int size = list.size();
int startIndex = size / 2;
for (int i = startIndex; i < size; i++) {
Integer val = list.get(i);
if (i == 0) {
list.add(1);
} else {
if (val == 0) {
list.add(0);
list.add(1);
} else {
list.add(1);
list.add(0);
}
}
}
return count(list, N, ++count);
}
思路三
创建一个那么大的数组来完成,感觉还是不美妙!
0
/ \
0 1
/ \ / \
0 1 1 0
/ \ / \ / \ / \
0 1 1 0 1 0 0 1
我们完全可以不用推算出第N行的整个数组,而是直接根据第K个结点逆向类推。
继续寻找线索。输出结果是一个 满二叉树
, 根节点 root
为 0
。 那么我们可以找到第N行的第K个元素的父节点,在寻找此父节点的父节点,一直类推找到根节点root
。
public int kthGrammar(int n, int k) {
if (n == 1) {
return 0;
}
int result = kthGrammar(n - 1, (k % 2 == 1 ? k / 2 + 1 : k / 2));
if (result == 0) {
return k % 2 == 0 ? 1 : 0;
} else {
return k % 2 == 0 ? 0 : 1;
}
}
网友评论