问题描述
问题分析
分析题目,这是一道经典的回溯法题目:
backtrack(res, nums, tmp, visited);
- res是结果集
- nums是候选集
- tmp是当前路径
- visit是访问控制集
基本算法思路是
backtrack(res, nums, tmp, visited){
//回溯结束条件(一般是tmp长度符合条件)
if(满足条件){
res添加路径tmp;
return;
}
//遍历候选集,继续递归
for(候选集){
//做选择(包括路径添加元素,和设置visit等)
tmp+1;
visit[i] = false;
//继续递归(backtrack(res, nums, tmp, visited))
backtrack(res, nums-1, tmp+1, visited)
//撤销选择(包括路径删除元素,和取消设置visit等)
tmp-1;
visit[i] = true;
}
}
解法:回溯法
- 时间复杂度:指数或者阶乘。
Java代码
package com.company;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
int[] a = {1, 2, 3};
List<List<Integer>> result = permute(a);
System.out.println(11);
}
static public List<List<Integer>> permute(int[] nums) {
//回溯法截止步数
int n = nums.length;
//结果数组
List<List<Integer>> result = new ArrayList<List<Integer>>();
//访问控制数组
boolean[] visited = new boolean[n];
backtrack(result, nums, new ArrayList<Integer>(), visited);
return result;
}
private static void backtrack(List<List<Integer>> result, int[] nums, ArrayList<Integer> temp, boolean[] visited) {
if (temp.size() == nums.length){
result.add(new ArrayList<>(temp));
return;
}
for (int i = 0; i < nums.length; i++) {
if (!visited[i]){
//做选择
visited[i] = true;
temp.add(nums[i]);
//回溯
backtrack(result, nums, temp, visited);
//撤销选择
visited[i] = false;
temp.remove((Integer) nums[i]);
}
}
}
}
结果分析
以上代码的执行结果:
执行时间 | 内存消耗 |
---|---|
2 ms | 38.5 MB |
来源:CSDN
作者:G_drive
链接:https://blog.csdn.net/G_drive/article/details/103592384