leetcode算法练习【47】 全排列 II

所有题目源代码:Git地址

题目

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

示例:

输入: [1,1,2]
输出:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]

方案:DFS+剪枝

  • 思路大体都差不太多,我是参考官方的思路
  • 先排序,那么大小相同的就会在一起,在这个数没访问过的前提下,我们只允许以下三种情况进入下一轮:
    • 第一个(i==0)
    • 与前一个相同但是前一个被访问过
    • 与前一个不同
  • 1、3两种比较好理解,2主要是为了强制相等的数的取法是按照顺序来的,这样就不会发生相等的数进行排列组合从而导致重复的情况发生
class Solution {
        public List<List<Integer>> permuteUnique(int[] nums) {
            List<List<Integer>> res = new ArrayList<>( );
            Arrays.sort(nums);
            DFS(res, nums, new ArrayDeque<>( ), new boolean[nums.length]);
            return res;
        }

        public void DFS(List<List<Integer>> res, int[] nums, Deque<Integer> arrange, boolean[] isVisited) {
            if (nums.length == arrange.size( )) {
                res.add(new ArrayList<>(arrange));
                return;
            }

            for (int i = 0; i < nums.length; i++) {
                //访问过
                if (!isVisited[i]) {
                    //第一个,或者相同但是前一个被访问过,或者不同
                    if (i == 0 || (nums[i]==nums[i-1]&&isVisited[i - 1])||nums[i]!=nums[i-1]) {
                        arrange.add(nums[i]);
                        isVisited[i] = true;
                        DFS(res, nums, arrange, isVisited);
                        arrange.removeLast( );
                        isVisited[i] = false;
                    }
                }
            }
        }
    }
复杂度计算
  • 时间复杂度:O(n!)
  • 空间复杂度:O(n!)
  • 二者最差的情况都是(n*n!),也就是不剪枝那种
原创文章 179 获赞 270 访问量 34万+

猜你喜欢

转载自blog.csdn.net/symuamua/article/details/106139337
今日推荐