标签:arr 排列 nums 重复 list pos 力扣 int swap
全排列[回溯]
力扣top46 全排列1
题目:
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
示例 2:
输入:nums = [0,1]
输出:[[0,1],[1,0]]
示例 3:
输入:nums = [1]
输出:[[1]]
提示:
1 <= nums.length <= 6
-10 <= nums[i] <= 10
nums
中的所有整数 互不相同
分析
本题可以使用回溯将所有可能得排列情况记录。
- 将当前数组分为左右两部分,左为已经选择并排列的部分,右为还没有选择排列的部分
[1 2|3 4]
- 从未选择的部分中选择一个数放到 当前填充位(swap替换位置即可)
[1 2 3|4]
- 然后继续递归直至填充完毕 将填充好的数组加入集合
list.add([1,2,3,4])
- 回溯,将swap交互的两个数再交换回来,然后选择下一个位置的数与 当前填充位替换
源代码
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>>list=new ArrayList<>();
backTracking(nums,list,0);
return list;
}
public void swap(int[] arr,int posA,int posB){
if(posA==posB)return;
int tmp=arr[posA];
arr[posA]=arr[posB];
arr[posB]=tmp;
}
public void backTracking(int[] nums,List<List<Integer>> list,int pos){
if(pos==nums.length){//边界
ArrayList<Integer>arr=new ArrayList<>();
for(int i:nums)arr.add(i);
list.add(arr);
}
for(int i=pos;i<nums.length;i++){
swap(nums,pos,i);
backTracking(nums,list,pos+1);
swap(nums,pos,i);
}
}
}
力扣top47 全排列2
题目:
给定一个含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例 1:
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
示例 2:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
提示:
1 <= nums.length <= 8
-10 <= nums[i] <= 10
nums
中的所有整数 可能相同
分析
使用回溯将所有可能得排列情况记录。
-
将当前数组分为左右两部分,左为已经选择并排列的部分,右为还没有选择排列的部分
[1 2|3 4]
-
从未选择的部分中选择一个数放到 当前填充位(swap替换位置即可)
只能选择未选择过的数字,使用
set
来保证不选择重复数字,避免额外多余的排列[1 2 3|4]
-
然后继续递归直至填充完毕 将填充好的数组加入集合
list.add([1,2,3,4])
-
回溯,将swap交互的两个数再交换回来,然后选择下一个位置的数与 当前填充位替换
源代码
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>>list=new ArrayList<>();
backTracking(nums,list,0);
return list;
}
public void swap(int[] arr,int posA,int posB){
int tmp=arr[posA];
arr[posA]=arr[posB];
arr[posB]=tmp;
}
public void backTracking(int[] nums,List<List<Integer>> list,int pos){
if(pos>=nums.length){
ArrayList<Integer>arr=new ArrayList<>();
for(int i:nums)arr.add(i);
list.add(arr);
return;
}
Set<Integer>set=new HashSet<>();
backTracking(nums,list,pos+1);
set.add(nums[pos]);
for(int i=pos+1;i<nums.length;i++){
if(set.contains(nums[i]))continue;
set.add(nums[i]);
swap(nums,pos,i);
backTracking(nums,list,pos+1);
swap(nums,pos,i);
}
}
}
标签:arr,排列,nums,重复,list,pos,力扣,int,swap 来源: https://blog.csdn.net/Ctrl_kun/article/details/121960396
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。