美文网首页
LeeCode刷题--K-th Symbol in Gramma

LeeCode刷题--K-th Symbol in Gramma

作者: faris_shi | 来源:发表于2018-02-19 08:03 被阅读37次

    题目

    原题地址

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

    继续寻找线索。输出结果是一个 满二叉树, 根节点 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 Gramma

          本文链接:https://www.haomeiwen.com/subject/roritftx.html