全排列ⅡJava

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

class Solution {
    List<Integer> path=new ArrayList<>();
    List<List<Integer>> res=new ArrayList<>();
    public List<List<Integer>> permuteUnique(int[] nums) {
        int []used=new int[nums.length];
        Arrays.fill(used,0);
        Arrays.sort(nums);
        backTrack(nums,used);
        return res;

    }
    private void backTrack(int []nums,int[]used){
        if(path.size()==nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(i>0&&nums[i]==nums[i-1]&&used[i-1]==0){
                continue;
            }
            if(used[i]==0){
                used[i]=1;
                path.add(nums[i]);
                backTrack(nums,used);
                path.remove(path.size()-1);
                used[i]=0;
            }
        }
    }
}

 为了观察回溯的过程,我在IDEA里面跑了一下,这样可以更加直观清楚的看到整个程序的运行思路

 

### 全排列问题的Java实现代码 以下是基于回溯算法实现的全排列问题的Java代码示例,能够生成给定数组的所有可能排列[^1]。 ```java import java.util.ArrayList; import java.util.List; public class Permutations { public static void main(String[] args) { int[] nums = {1, 2, 3}; List<List<Integer>> permutations = generatePermutations(nums); System.out.println(permutations); } public static List<List<Integer>> generatePermutations(int[] nums) { List<List<Integer>> result = new ArrayList<>(); backtrack(result, new ArrayList<>(), nums); return result; } private static void backtrack(List<List<Integer>> result, List<Integer> tempList, int[] nums) { if (tempList.size() == nums.length) { result.add(new ArrayList<>(tempList)); // 当临时列表大小等于数组长度时,添加到结果中 } else { for (int i = 0; i < nums.length; i++) { if (tempList.contains(nums[i])) { continue; // 如果当前数字已经在临时列表中,则跳过 } tempList.add(nums[i]); // 做出选择 backtrack(result, tempList, nums); // 递归调用 tempList.remove(tempList.size() - 1); // 撤销选择 } } } } ``` #### 代码解析 - **主方法**:`main` 方法初始化一个整数数组并调用 `generatePermutations` 方法生成所有排列。 - **核心逻辑**: - 使用回溯算法生成所有可能的排列。 - 在每次递归中,尝试将未使用的数字加入到当前排列中,并继续递归处理剩余的数字[^2]。 - 当当前排列的长度等于数组长度时,将其添加到结果列表中。 - **时间复杂度**:O(n!),其中 n 是数组的长度,因为需要生成所有可能的排列。 - **空间复杂度**:O(n),递归调用栈的深度为 n。 ### 另一种实现方式 以下是一种通过交换元素位置来生成全排列Java代码[^3]。 ```java import java.util.ArrayList; import java.util.List; public class Permute { public static List<List<Integer>> permute(int[] nums) { List<List<Integer>> ans = new ArrayList<>(); process(nums, 0, ans); return ans; } public static void process(int[] nums, int index, List<List<Integer>> ans) { if (index == nums.length) { ans.add(toList(nums)); // 将数组转换为列表并添加到结果中 } else { for (int i = index; i < nums.length; i++) { swap(nums, i, index); // 交换元素以生成新的排列 process(nums, index + 1, ans); // 递归处理下一个索引 swap(nums, i, index); // 撤销交换操作 } } } public static void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } public static List<Integer> toList(int[] nums) { List<Integer> list = new ArrayList<>(); for (int num : nums) { list.add(num); } return list; } public static void main(String[] args) { int[] nums = {1, 2, 3}; List<List<Integer>> permutations = permute(nums); System.out.println(permutations); } } ``` #### 代码解析 - **主方法**:`main` 方法初始化一个整数数组并调用 `permute` 方法生成所有排列。 - **核心逻辑**: - 通过交换数组中的元素位置生成所有可能的排列。 - 在每次递归中,固定当前索引的元素,并对剩余部分进行递归处理。 - 当索引达到数组末尾时,将当前排列添加到结果列表中。 - **时间复杂度**:O(n!),与第一种方法相同。 - **空间复杂度**:O(n),递归调用栈的深度为 n。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值