题目:
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
求全排列,没有重复的元素
解法1:
调用函数next_permutation
首先输入的序列不一定是排序好的,首先要先排序,注意使用do while 结构,第一个排列也要加进去
c++:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
do{
res.push_back(nums);
} while(next_permutation(nums.begin(),nums.end()));
return res;
}
};
解法2:
用LeetCode 刷题记录31. 31. Next Permutation的函数
函数需要点改进,原函数没有返回数据,现在我们需要返回true或者false,表示是否结束
- 如果排列为1位,自然没有下一个排列,返回false
- 如果最后需要整个反转即说明到达了最后一个排列,如3 2 1 ,不需要再进行了,返回false
c++:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
do{
res.push_back(nums);
} while(nextPermutation(nums));
return res;
}
bool nextPermutation(vector<int>& nums) {
int n = nums.size();
if(n <= 1) return false;
int i = n - 2;
int j = n - 1;
while(i >= 0 && nums[i] >= nums[i + 1]) --i;
if(i >= 0){
while(j >= 0 && nums[j] <= nums[i]) --j;
swap(nums[i] , nums[j]);
}
if(i == -1){
//reverse(nums.begin(), nums.end());
return false;
} else {
reverse(nums.begin() + i + 1 , nums.end());
return true;
}
}
};
java:
java需要将int[] 数组转成List list,详见Java:ArrayList和数组int[]的相互转化
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
List<Integer> list = null;
do{
list = Arrays.stream(nums).boxed().collect(Collectors.toList());
res.add(list);
} while(nextPermutation(nums));
return res;
}
public boolean nextPermutation(int[] nums) {
int n = nums.length;
if(nums == null || n <= 1) return false;
int i = n - 2;
int j = n - 1;
while(i >= 0 && nums[i] >= nums[i + 1]) --i;
if(i >= 0){
while(j >= 0 && nums[j] <= nums[i]) --j;
swap(nums, i, j);
}
if(i == -1){
//reverse(nums, 0 , n - 1);
return false;
} else {
reverse(nums, i + 1 , n - 1);
return true;
}
}
private void reverse(int[] nums, int start, int end){
int i = start;
int j = end;
while(i < j){
swap(nums, i, j);
i++;
j--;
}
}
private void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
python:
- python中没有do while 函数
- append函数添加nums时,添加的是引用,所以后面添加的会改变前面的元素,所以要用深拷贝append操作被覆盖 ,此外可以用res.append(nums[:])来创建新的对象
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
nums.sort()
temp = copy.deepcopy(nums)
res.append(temp)
while self.nextPermutation(nums):
temp = copy.deepcopy(nums)
res.append(temp)
return res
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
n = len(nums)
if nums == None or n <= 1: return False
i = n - 2
j = n - 1
while i >= 0 and nums[i] >= nums[i + 1]: i -= 1
if i >= 0:
while j >= 0 and nums[j] <= nums[i]: j -= 1
nums[i] , nums[j] = nums[j], nums[i]
if i == -1:
return False
else:
start = i + 1
end = n - 1
while start < end:
nums[start] , nums[end] = nums[end], nums[start]
start, end = start + 1, end - 1
return True
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
nums.sort()
temp = copy.deepcopy(nums)
res.append(temp)
print res
while self.nextPermutation(nums):
# temp = copy.deepcopy(nums)
# res.append(temp)
res.append(nums[:])
return res
def nextPermutation(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
n = len(nums)
if nums == None or n <= 1: return False
i = n - 2
j = n - 1
while i >= 0 and nums[i] >= nums[i + 1]: i -= 1
if i >= 0:
while j >= 0 and nums[j] <= nums[i]: j -= 1
nums[i] , nums[j] = nums[j], nums[i]
if i == -1:
start = i + 1
end = n - 1
while start < end:
nums[start] , nums[end] = nums[end], nums[start]
start, end = start + 1, end - 1
print nums
return False
else:
start = i + 1
end = n - 1
while start < end:
nums[start] , nums[end] = nums[end], nums[start]
start, end = start + 1, end - 1
return True
解法3:
递归法
因为是全排列,所以递归函数需要从0开始,为了防止重复,设置一个bool 数组看是否访问过
c++:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
int n = nums.size();
vector<int> path,visited(n, 0);
DFS(nums, path, visited,res,0);
return res;
}
void DFS(vector<int>& nums,vector<int>& path,vector<int>& visited,vector<vector<int>>& res,int index) {
if(index == nums.size()){
res.push_back(path);
return;
}
for(int i = 0; i < nums.size(); i++){
if(visited[i] == 0){
path.push_back(nums[i]);
visited[i] = 1;
DFS(nums, path, visited,res,index + 1);
path.pop_back();
visited[i] = 0;
}
}
}
};
java:
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean[] visited = new boolean[nums.length];
DFS(nums, path, res, visited, 0);
return res;
}
private void DFS(int[] nums,List<Integer> path,List<List<Integer>> res,boolean[] visited,int index){
if(index == nums.length){
res.add(new ArrayList<>(path));
return;
}
for(int i = 0; i < nums.length; ++i){
if(visited[i] == true) continue;
path.add(nums[i]);
visited[i] = true;
DFS(nums, path, res,visited , index + 1);
path.remove(path.size() - 1);
visited[i] = false;
}
}
}
python:
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
path = []
visited = [0] * len(nums)
self.DFS(nums, path, res, visited, 0)
return res
def DFS(self, nums, path, res,visited,index):
if index == len(nums):
res.append(path)
return
for i in xrange(len(nums)):
if visited[i] == 1: continue
visited[i] = 1
self.DFS(nums, path + [nums[i]], res, visited, index + 1)
#self.DFS(nums, path, res, visited, index + 1)
visited[i] = 0
解法4:
递归法:优化
DFS只有两个参数,首先去掉了临时结果path,直接用nums代替,另外一个参数为start
start的含义是nums数组中[0 : start -1]的数字已经确定好了
这样递归基就确定了,start == n(数组的长度)时,说明所有的数字已经确定好了,直接加入结果就好
递归的过程就是start的数字依次与后序的数字交换
以 123 为例,红色的为已确定的数字
c++:
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
DFS(nums, res,0);
return res;
}
void DFS(vector<int>& nums,vector<vector<int>>& res,int start) {
if(start == nums.size()){
res.push_back(nums);
return;
}
for(int i = start; i < nums.size(); i++){
swap(nums[start], nums[i]);
DFS(nums,res,start + 1);
swap(nums[start], nums[i]);
}
}
};
java:
java中swap函数如果用异或^ 交换的话,自己和自己不能交换,自己与自己异或结果为0
异或运算中有这样的一个性质:a == a^b^b,
计算过程是:
a = a ^ b
b = b ^ (a^b)
a = (a^b) ^ (b^a^b)
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
DFS(nums, res, 0);
return res;
}
private void DFS(int[] nums,List<List<Integer>> res,int start){
if(start == nums.length){
List<Integer> temp = new ArrayList<Integer>();
for (int i = 0; i < nums.length; i++) {
temp.add(nums[i]);
}
res.add(new ArrayList<>(temp));
return;
}
for(int i = start; i < nums.length; ++i){
if(i != start){
swap(nums,start,i);
}
DFS(nums, res, start + 1);
if(i != start){
swap(nums,start,i);
}
}
}
// private void swap(int[] nums, int i, int j){
// int temp = nums[i];
// nums[i] = nums[j];
// nums[j] = temp;
// }
private void swap(int[] nums, int i, int j){
nums[i] ^= nums[j];
nums[j] ^= nums[i];
nums[i] ^= nums[j];
}
}
python :
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
self.DFS(nums, res, 0)
return res
def DFS(self, nums, res,start):
if start == len(nums):
res.append(nums[:])
return
for i in xrange(start,len(nums)):
nums[start], nums[i] = nums[i],nums[start]
self.DFS(nums, res, start + 1)
nums[start], nums[i] = nums[i],nums[start]