力扣练习-全排列 II

我爱海鲸 2025-04-15 13:56:33 力扣、中级算法

简介力扣、中级算法

https://leetcode.cn/problems/permutations-ii/description/

 

给定一个可包含重复数字的序列 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

解法一(java):

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        boolean[] uses = new boolean[nums.length];
        backStarck(result,new ArrayList<>(),nums,uses);
        return result;
    }

    public void backStarck(List<List<Integer>> result,List<Integer> tmpList,int[] nums,boolean[] uses) {
        if (tmpList.size() == nums.length) {
            result.add(new ArrayList<>(tmpList));
            return;
        }
        for (int i = 0 ; i < nums.length ; i++) {
            if (uses[i] || (i > 0 && nums[i] == nums[i-1] && !uses[i-1])) {
                continue;
            }
            uses[i] = true;
            tmpList.add(nums[i]);
            backStarck(result,tmpList,nums,uses);
            tmpList.remove(tmpList.size() - 1);
            uses[i] = false;
        }

    }
}

思路:回溯法,参考http://www.haijin.xyz/article/566

  1. 排序:首先对数组进行排序,使相同数字相邻,便于后续剪枝处理。

  2. 回溯函数backtrack 是核心递归函数,用于生成排列。

    • 终止条件:当前排列长度等于原数组长度时,将当前排列加入结果集。

    • 循环遍历:遍历数组中的每个数字。

    • 剪枝条件:如果当前数字已被使用,或者与前一个数字相同且前一个数字未被使用(避免重复),则跳过。

    • 递归调用:标记当前数字为已使用,加入当前排列,递归调用,然后回溯(恢复状态)。

  3. 结果返回:最终返回所有不重复的排列。

你好:我的2025