给定一个没有重复数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
(1)
方法:字典法
思路:
(1)拿到全部排序,并且按照字典顺序;
(2)现将数组排序,然后判断是否右下一个排列,参考下一个排列
(3)循环拿到所有的排列组合,直到没有下一个排列,也就是排列已经是当前数组元素按照字典顺序倒序的组合;
class Solution {
public List<List<Integer>> permute(int[] nums) {
//字典法
Arrays.sort(nums);//先排序
List<List<Integer>> res = new ArrayList<>();
do {
List<Integer> temp = new ArrayList<>();
for (Integer i : nums)
temp.add(i);
res.add(temp);
} while (nextPermute(nums));
return res;
/**int end = nums.length - 1;
List<List<Integer>> res = new ArrayList<>();
permute(nums, res, 0, end);
return res;**/
}
//判断是否有下一个全排列,有则进行下一个排列并且拿到true,无则false
private boolean nextPermute(int[] nums) {
int end = nums.length - 2;
while (end >= 0 && nums[end + 1] <= nums[end])
end --;
if (end >= 0) {
int temp = nums.length - 1;
while (end >= 0 && nums[end] > nums[temp])
temp --;
swap(nums, end, temp);
reverse(nums, end + 1);
} else {
return false;
}
return true;
}
//换位
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
//反转
private void reverse(int[] nums, int start) {
int end = nums.length - 1;
while (start < end) {
swap(nums, start, end);
start ++;
end --;
}
}
(2)
方法:递归法
思路:
1,元素和它例如数组[1,3,4,2];
2,首先保持第一个元素不变,就是[3,4,2]的排列,然后保持3不变就是[4,2]的排列,在保持4不变,就只剩一个元素,就只有一种元素了,所以排列就是[1,3,4,2],往回一步,4要变那就只能4和2换位就变成了[1,3,2,4];再往回走,那就变3,则3和4,2相互换位,然后得到[1,4,3,2], [1,4,23],[1,2,4,3][1,2,3,4];
3,然后再要改变第一个元素,则将其与后面的元素换位,经过递归实现上述算法;
class Solution {
public List<List<Integer>> permute(int[] nums) {
int end = nums.length - 1;
List<List<Integer>> res = new ArrayList<>();
permute(nums, res, 0, end);
return res;
}
//换位
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public void permute(int[] nums, List<List<Integer>> res, int begin, int end) {
//递归法,两两换位
//递归结束条件,两两换位后,begin = end;
if (begin == end) {// 完成一次全排列
List<Integer> temp = new ArrayList<>();
for (Integer i : nums)
temp.add(i);
res.add(temp);
return;
} else {
for (int i = begin; i <= end; i ++) {//换位
swap(nums, begin, i);//锁定位
permute(nums, res, begin + 1, end);//后续位
swap(nums, begin, i);
}
}
}
}