LeetCode 89 - Gray Code


http://www.geeksforgeeks.org/given-a-number-n-generate-bit-patterns-from-0-to-2n-1-so-that-successive-patterns-differ-by-one-bit/
The gray code is a binary numeral system where two successive values differ in only one bit.
Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.

n-bit Gray Codes can be generated from list of (n-1)-bit Gray codes using following steps.
1) Let the list of (n-1)-bit Gray codes be L1. Create another list L2 which is reverse of L1.
2) Modify the list L1 by prefixing a ’0′ in all codes of L1.
3) Modify the list L2 by prefixing a ’1′ in all codes of L2.
4) Concatenate L1 and L2. The concatenated list is required list of n-bit Gray codes.
For example, following are steps for generating the 3-bit Gray code list from the list of 2-bit Gray code list.
L1 = {00, 01, 11, 10} (List of 2-bit Gray Codes)
L2 = {10, 11, 01, 00} (Reverse of L1)
Prefix all entries of L1 with ’0′, L1 becomes {000, 001, 011, 010}
Prefix all entries of L2 with ’1′, L2 becomes {110, 111, 101, 100}
Concatenate L1 and L2, we get {000, 001, 011, 010, 110, 111, 101, 100}
http://huntfor.iteye.com/blog/2060142
格雷码, 提示中称:[0,2,3,1]也是一组合法的格雷码,把我彻底搞糊涂了,既然如此,为什么要返回[0,1,3,2]而不能返回[0,2,3,1]呢?后来手贱去百度了一下格雷码。尼玛....
看下格雷码的特征:
n == 1时,[0,1]
n == 2时,[00,01,11,10]
n == 3时,[000,001,011,010,110,111,101,100]
1位格雷码有两个码字
(n+1)位格雷码中的前2n个码字等于n位格雷码的码字,按顺序书写,加前缀0
(n+1)位格雷码中的后2n个码字等于n位格雷码的码字,按逆序书写,加前缀1
前后两部分的后n - 1位是对称的。
n的格雷码,就是n-1的格雷码,再加上它们的逆序前面多一个1。
当n=2时
00
01
11
10
当n=3时
000
001
011
010
110
111
101
100
可以发现,n的格雷码,就是n-1的格雷码,再加上它们的逆序前面多一个1。
    public List<Integer> grayCode(int n) {
        List<Integer> res = new ArrayList<Integer>();
        // 加入初始值0
        res.add(0);
        for(int i = 0; i < n; i++){
            // 每一轮的最高位
            int highestBit = 1 << i;
            int size = res.size();
            // 逆序添加上一轮里出现的数,不过开头加上这一轮的最高位
            for(int j = size - 1; j >= 0; j--){
                int num = res.get(j);
                num += highestBit;
                res.add(num);
            }
        }
        return res;
    }
工业中的第i个格雷码是这么生成的:(i>>1)^i
i是指下标,从0开始,对于n的格雷码序列,一共有2^n个数
    public List<Integer> grayCode(int n) {
        List<Integer> res = new ArrayList<Integer>();
        for(int i = 0; i < 1 << n; i++) res.add((i >> 1)^i);
        return res;
    }
My idea is to generate the sequence iteratively. For example, when n=3, we can get the result based on n=2. 00,01,11,10 -> (000,001,011,010 ) (110,111,101,100). The middle two numbers only differ at their highest bit, while the rest numbers of part two are exactly symmetric of part one. It is easy to see its correctness. Code is simple:
public List<Integer> grayCode(int n) {
    List<Integer> rs=new ArrayList<Integer>();
    rs.add(0);
    for(int i=0;i<n;i++){
        int size=rs.size();
        for(int k=size-1;k>=0;k--)
            rs.add(rs.get(k) | 1<<i);
    }
    return rs;
}
We can see that the last two digits of 4 codes at the bottom is just the descending sequence of the first 4 codes. The first 4 codes are 0, 1, 3, 2. So, we can easily get the last 4 codes: 2 + 4, 3 + 4, 1 + 4, 0 + 4, which is 6, 7, 5, 4. We can keep doing this until we reach n digits.
    public List<Integer> grayCode(int n) {
        List<Integer> ret = new LinkedList<>();
        ret.add(0);
        for (int i = 0; i < n; i++) {
            int size = ret.size();
            for (int j = size - 1; j >= 0; j--)
                ret.add(ret.get(j) + size);
        }
        return ret;
    }


void generateGrayarr(int n)
{
    // base case
    if (n <= 0)
        return;
    // 'arr' will store all generated codes
    vector<string> arr;
    // start with one-bit pattern
    arr.push_back("0");
    arr.push_back("1");
    // Every iteration of this loop generates 2*i codes from previously
    // generated i codes.
    int i, j;
    for (i = 2; i < (1<<n); i = i<<1)
    {
        // Enter the prviously generated codes again in arr[] in reverse
        // order. Nor arr[] has double number of codes.
        for (j = i-1 ; j >= 0 ; j--)
            arr.push_back(arr[j]);
        // append 0 to the first half
        for (j = 0 ; j < i ; j++)
            arr[j] = "0" + arr[j];
        // append 1 to the second half
        for (j = i ; j < 2*i ; j++)
            arr[j] = "1" + arr[j];
    }
    // print contents of arr[]
    for (i = 0 ; i < arr.size() ; i++ )
        cout << arr[i] << endl;
}
For example, given n = 2, return [0,1,3,2]. Its gray code sequence is:
00 - 0  01 - 1  11 - 3  10 - 2

When n=3:
000
001
011
010
110
111 
101
100
From: http://www.darrensunny.me/leetcode-gray-code/
We can construct a gray code sequence of length n using a gray code sequence of length n1 . Specifically, adding a preceding '0' to each of the numbers in binary format preserves the property that two successive values differ in only one bit. We do it and name the new sequence as s1. If we reverse the order of the numbers, and add a preceding '1' to each, the property is preserved as well.
public ArrayList<Integer> grayCode(int n) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if (n < 0)      // Invalid input
            return result;
        result.add(0);
        if (n == 0)     // No bit
            return result;
        result.add(1);  // With one bit
        // Iteratively contruct the grey code of n bits on that of n-1 bits
        // gc(n) = gc(n-1) ... gc'(n-1)+2^(n-1), where
        // gc'(n-1) means the reverse sequence of gc(n-1), and +2^(n-1) means adding
        // 2^(n-1) to each number in the sequence
        for (int i = 2; i <= n; i++) {
            int size = result.size();
            for (int j = size-1; j >= 0; j--)
                result.add(result.get(j)+(1<<(i-1)));
        }
        return result;
    }
vector<int> grayCode(int n)
{
  vector<int> ret;
  int size = 1 << n;
  for(int i = 0; i < size; ++i)
ret.push_back((i >> 1)^i);
  return ret;
}
X. DFS
Gray Code | 生成相邻两个数只有1位不同的序列,每个数有n bit
public ArrayList<Integer> grayCode(int n) {
    if (n == 0) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(0);
        return list;
    }
    return getGrayCode(n - 1);
}
private ArrayList<Integer> getGrayCode(int pos) {
    if (pos == 0) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(0);
        list.add(1);
        return list;
    }
    ArrayList<Integer> result = new ArrayList<Integer>();
    ArrayList<Integer> startsWithZero = getGrayCode(pos - 1);
    ArrayList<Integer> startsWithOne = new ArrayList<Integer>();
    for (int i = startsWithZero.size() - 1; i >= 0; i--) {
        startsWithOne.add(startsWithZero.get(i) + (1 << pos));
    }
    result.addAll(startsWithZero);
    result.addAll(startsWithOne);
    return result;
}
https://leetcode.com/discuss/73590/java-easy-version-to-understand
public static List<Integer> grayCode(int n) { if (n < 0) return new ArrayList<Integer>(); if (n == 0) { List<Integer> list = new ArrayList<Integer>(); list.add(0); return list; } List<Integer> tmp = grayCode(n - 1); List<Integer> result = new ArrayList<Integer>(tmp); int addNumber = 1 << (n - 1); for (int i = tmp.size() - 1; i >= 0; i--) { result.add(addNumber + tmp.get(i)); } return result; }

EPI Solution: Compute a Gray code GrayCode.java

  public static List<Integer> grayCode(int numBits) {
    if (numBits == 0) {
      return Arrays.asList(0);
    }
    if (numBits == 1) {
      return Arrays.asList(0, 1);
    }

    // These implicitly begin with 0.
    List<Integer> grayCodeNumBitsMinus1 = grayCode(numBits - 1);
    // Prepend 1 to entries in grayCodeNumBitsMinus1.
    int leadingBitOne = 1 << (numBits - 1);
    List<Integer> reflection = new ArrayList<>();
    // Process in reverse order to achieve reflection of grayCodeNumBitsMinus1.
    for (int i = grayCodeNumBitsMinus1.size() - 1; i >= 0; --i) {
      reflection.add(leadingBitOne + grayCodeNumBitsMinus1.get(i));
    }
    List<Integer> result = new ArrayList<>(grayCodeNumBitsMinus1);
    result.addAll(reflection);
    return result;
  }
Also refer to http://www.darrensunny.me/leetcode-gray-code/
http://www.programering.com/a/MDO0kDMwATM.html
Gray code to binary number
Read full article from 水中的鱼: [LeetCode] Gray Code 解题报告

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts