题意描述:
给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
解题思路:
Alice: 这道题和子集那道题应该是一样的,也是递归的解法。
Bob:我先找找找规律吧。
Alice: 就是这个意思,三个元素的全排列是在两个元素的全排列基础之上得到的,只需要将第三个元素插入到 两个元素的全排列的 “缝隙” 上就可以了。
Bob: 又是递归的解法,不过所有递归都可以改写成循环,写成循环应该会更快一点,不过可能没这么好理解。
Alice: 😎😎
代码:
Python 方法一: 递归。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
return self.getAnswer(nums, [[]])
def getAnswer(self, nums: List[int], ans: List[List[int]]) -> List[List[int]]:
if len(nums) == 0:
# 递归终止条件
return ans
else:
tmp = []
for x in ans:
# 对于前面已有的排列
for z in range(0, len(x)+1):
# 在每个可能的位置插入新的元素
innerTmp = []
innerTmp[:] = x[:]
innerTmp.insert(z, nums[0])
tmp.append(innerTmp)
ans = tmp
# 更新已有的排列
nums.pop(0)
return self.getAnswer(nums, ans)
Python 方法二: 循环。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
ans = [[]]
for x in nums:
# 每次向已有排列中插入一个元素
tmpAns = []
for previous in ans:
# 对于 已有的 每一个排列
tmp = []
for index in range(0, len(previous)+1):
# 在 合适的位置插入元素
tmp[:] = previous[:]
# 硬拷贝 已有的 排列
tmp.insert(index, x)
tmpAns.append(tmp[:])
# 一定要硬拷贝
ans = tmpAns
return ans
Java 方法二: 循环,硬拷贝比较耗时哦,┓( ´∀` )┏。
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ans = new ArrayList();
List<List<Integer>> tmpAns = new ArrayList();
List<Integer> tmp = new ArrayList();
ans.add(tmp);
for(int i=0; i<nums.length; ++i){
// 将每个元素 插入到 已有的排列中去
for(int j=0; j<ans.size(); ++j){
// 对于 已有的每个排列
int endIndex = ans.get(j).size() + 1;
for(int k=0; k<endIndex; ++k){
// 对于已有排列的每个位置
clone(ans.get(j), tmp);
tmp.add(k, nums[i]);
tmpAns.add(getCloned(tmp));
}
}
ans.clear();
clone2(tmpAns, ans);
tmpAns.clear();
}
return ans;
}
public void clone(List<Integer>source, List<Integer>target){
// 将一个ArrayList 克隆到另一个,深拷贝。
target.clear();
for(int i=0; i<source.size(); ++i){
target.add(source.get(i));
}
return;
}
public List<Integer> getCloned(List<Integer>source){
// 返回一个ArrayList 的深拷贝。
List<Integer>tmp = new ArrayList();
for(int i=0; i<source.size(); ++i){
tmp.add(source.get(i));
}
return tmp;
}
public void clone2(List<List<Integer>>source, List<List<Integer>>target){
// 将一个 List of List 深拷贝到 另一个。
target.clear();
for(int i=0; i<source.size(); ++i){
target.add(getCloned(source.get(i)));
}
return;
}
}
易错点:
- 全排列内部的不同排列之间的顺序可以不一样。如
[[3,2,1],[2,3,1],[2,1,3],[3,1,2],[1,3,2],[1,2,3]]
与[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
是相等的全排列。 Python
/Java
中的浅拷贝和硬拷贝的结果是不一样的。
总结: