/* * 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; }