给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]]
解题思路:回溯算法
回溯算法又通常有个别致的名字-走不通就退回,又称试探法,是一种选优搜索法。从选择第一个元素开始做,然后递归的做出下一个选择,直到所有元素都使用过用来做排列。算法书写也基本固定,可以遵循以下模板书写程序:
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
C/C++题解:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;//结果集
vector<int> visited(nums.size(),0);//回溯标记
vector<int> tmp;//临时组合容器
backtrack(res, nums, tmp, visited);//回溯找结果
return res;}
void backtrack(vector<vector<int>> &res, vector<int>& nums, vector<int>& tmp, vector<int>& visited) {
if (tmp.size() == nums.size()) {//tmp存放一种组合,所有元素都添加进组合
res.push_back(tmp);//则长度和源数组相同
return;}
for (int i = 0; i < nums.size(); i++) {//使用源数组中的元素
if (visited[i] == 1) continue;
visited[i] = 1;//使用,即在本回合找一个组合时把元素标记过使用过
tmp.push_back(nums[i]);
backtrack(res, nums, tmp, visited);//接着以tmp中的元素为前缀,组合元素补齐
visited[i] = 0;//在开始找下一个组合前,重置为0,方便找下一种组合
tmp.pop_back();}}};//同样存放组合的临时容器也清空
Debug结果:
Java题解:
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();//结果集
int[] visited = new int[nums.length];//回溯标记
backtrack(res, nums, new ArrayList<Integer>(), visited);//回溯找结果
return res;}
private void backtrack(List<List<Integer>> res, int[] nums, ArrayList<Integer> tmp, int[] visited) {
if (tmp.size() == nums.length) {//tmp存放一种组合,所有元素都添加进组合
res.add(new ArrayList<>(tmp));//则长度和源数组相同
return;}
for (int i = 0; i < nums.length; i++) {//使用源数组中的元素
if (visited[i] == 1) continue;
visited[i] = 1;//使用,即在本回合找一个组合时把元素标记过使用过
tmp.add(nums[i]);
backtrack(res, nums, tmp, visited);//接着以tmp中的元素为前缀,组合元素补齐
visited[i] = 0;//在开始找下一个组合前,重置为0,方便找下一种组合
tmp.remove(tmp.size() - 1);}}}//同样存放组合的临时容器也清空
Debug结果:
Python题解:
class Solution(object):
def permute(self, nums):
""":type nums: List[int]:rtype: List[List[int]]"""
def backtrack(nums, res, tmp):
if not nums: #遍历完源元素数组,此时tmp里有了完整的一种排列
res.append(tmp)#添加到结果集中,重新找新的排列
return
for i in range(len(nums)):#遍历当前元素添加进临时存放一种组合的容器里
backtrack(nums[:i] + nums[i+1:], res, tmp + [nums[i]])
res = [] #结果集
backtrack(nums, res, [])
return res
Debug结果:
更多讲解可前往公众号免费获取