原题链接:https://leetcode-cn.com/problems/gray-code/
题目描述:
知识点:递归、回溯
思路:回溯法寻找格雷码
本题是常规的回溯算法题。
需要注意的一点是,本题并不要求寻找所有的格雷码组合,所以一旦寻找到了一个格雷码,立即break跳出for循环。如果要找出所有的格雷码,其时间复杂度是很高的。
因为有break跳出循环,所以时间复杂度不好分析,但在最差情况下是O(n * 2 ^ n)。空间复杂度即递归深度,是O(2 ^ n)。
JAVA代码:
public class Solution {
List<Integer> retList;
public List<Integer> grayCode(int n) {
retList = new ArrayList<>();
retList.add(0);
if(n == 0){
return retList;
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < n; i++) {
stringBuilder.append("0");
}
grayCode(retList, stringBuilder, n);
return retList;
}
private void grayCode(List<Integer> list, StringBuilder stringBuilder, int n){
if(list.size() == Math.pow(2, n)){
retList = new ArrayList<>(list);
return;
}
for (int i = 0; i < stringBuilder.length(); i++) {
if(retList.size() == Math.pow(2, n)){
break;
}
if(stringBuilder.charAt(i) == '0'){
stringBuilder.replace(i, i + 1, "1");
int num = Integer.parseInt(stringBuilder.toString(), 2);
if(!list.contains(num)){
list.add(num);
grayCode(list, stringBuilder, n);
list.remove(list.size() - 1);
}
stringBuilder.replace(i, i + 1, "0");
}else{
stringBuilder.replace(i, i + 1, "0");
int num = Integer.parseInt(stringBuilder.toString(), 2);
if(!list.contains(num)){
list.add(num);
grayCode(list, stringBuilder, n);
list.remove(list.size() - 1);
}
stringBuilder.replace(i, i + 1, "1");
}
}
}
}