89. Gray Code

    /*
     * 89. Gray Code 
     * 2016-5-14 by Mingyang
     * 因为格雷码要求两个之间位数只差一位,也就是最简便的一种方法就是,把第一位变了,后面的倒叙过来就好
     * ,因为所有的前半部分都不变,两部分交点的后半部分都是一样的
     * 只是前缀变了,所以只需要倒过来就好了。算法复杂度是O(2+2^2+...+2^n-1)=
     * O(2^n),所以是指数量级的,因为是结果数量无法避免。空间复杂度则是结果的大小,也是O(2^n)。
     * 先是我的代码,然后后面是网上大神的代码
     */
    public List<Integer> grayCode1(int n) {
        List<Integer> res = new ArrayList<Integer>();
        if (n == 0) {
            res.add(0);
            return res;
        }
        if (n == 1) {
            res.add(0);
            res.add(1);
            return res;
        }
        List<Integer> temp = grayCode(n - 1);
        int num = (int) Math.pow(2.0, n - 1.0);
        for (int i = 0; i < temp.size(); i++) {
            res.add(temp.get(i));
        }
        for (int i = temp.size() - 1; i >= 0; i--) {
            res.add(temp.get(i) + num);
        }
        return res;
    }
    //网上的代码,一样的思路,实现的不一样
    public List<Integer> grayCode(int n) {
        List<Integer> res = new ArrayList<Integer>();
        if (n < 0)
            return res;
        if (n == 0) {
            res.add(0);
            return res;
        }
        res.add(0);
        res.add(1);
        for (int i = 2; i <= n; i++) {
            int size = res.size(); // 因为前半部分都是前面加的0,对结果毫无影响,所以只用管后半部分,从后到前依次递减,然后分别加上1往左移到该移的位置就好了
            for (int j = size - 1; j >= 0; j--) {
                res.add(res.get(j) + (1 << (i - 1)));
            }
        }
        return res;
    }
原文地址:https://www.cnblogs.com/zmyvszk/p/5494841.html