0
点赞
收藏
分享

微信扫一扫

【剑指Offer】含有重复元素集合的全排列

  • 力扣链接:含有重复元素集合的全排列
  • 题目:给定一个可包含重复数字的整数集合 nums ,按任意顺序 返回它所有不重复的全排列。
  • 思路:
  1. 这个题需要用到回溯法。
  2. 用 res 存放最终所有结果的集合,path 存放每次递归得出的结果。
  3. 布尔型的 visited 数组大小和整型的 nums 数组一样大,用来存放每个数字的状态,ture 为已经访问过,false 为还没有访问过。
  4. 首先对需要用到的数据进行初始化。将 nums 数组进行排序,n 为数组长度;然后调用回溯函数 backtracking,将当前数字的下标 index 传入回溯函数。
  5. 在回溯函数中,第一个 if 判断,如果当前下标等于数组长度,就保存当前结果并且return。第二个 for 循环中,第一个 if 判断的是当前数字是否访问过,若访问过,则 continue 跳出本次循环;第二个 if 判断,如果下标 i 合法并且存在两数字相等并且上一个数字没有访问过,则 continue 跳出本次循环。如果两个 if 判断都为 false 则将这个数字放到 path 中,将当前下标对应的 visited 数组的值置为 ture ,接着递归下一个下标 index+1,
  • 具体实现:
class Solution 
{
    int [] nums;
    int n;
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();
    boolean [] visited;

    public List<List<Integer>> permuteUnique(int[] nums) 
    {
        Arrays.sort(nums);
        this.nums = nums;
        this.n = nums.length;
        this.visited = new boolean [n];
        backtracking(0);
        return res;
    }
    
    public void backtracking(int index)
    {
        if (index == n)
        {
            res.add(new ArrayList<>(path));
            return ;
        }

        for (int i = 0; i < n; i ++)
        {
            if (visited[i] == true)
                continue;
            if (0 < i && nums[i - 1] == nums[i] && visited[i - 1] == false)
                continue;
            path.add(nums[i]);
            visited[i] = true;
            backtracking(index + 1);
            visited[i] = false;
            path.remove(path.size() - 1);
        }
    }

}
举报

相关推荐

0 条评论