LeeCode刷题--K-th Symbol in Grammar

题目

原题地址

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 list = new ArrayList(CAPACITY);
    list.add(0);
    count(list, N, 0);
    System.out.println(list);
    return list.get(K - 1);
}

public List count(List 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个结点逆向类推。

继续寻找线索。输出结果是一个 满二叉树, 根节点 root0。 那么我们可以找到第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;
    }
}

你可能感兴趣的:(LeeCode刷题--K-th Symbol in Grammar)