47. 全排列 II

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 
 
思路:
参考46题 本题还要额外考虑剪枝 去除重复结果
当只要遇到起点一样,就有可能产生重复。
还要考虑不同深度情况下,11′2不应该误剪
 1  public List<List<Integer>> permuteUnique(int[] nums) {
 2         int length = nums.length;
 3         if (length == 0) return null;
 4         Stack<Integer> path = new Stack<>();//容器
 5         boolean[] used = new boolean[length];//记录该数字是否加入容器中
 6         int depth = 0;//深度
 7         List<List<Integer>> ans = new ArrayList<>();//答案
 8         Arrays.sort(nums);//排序
 9 
10         arrary(nums, length, depth, used, path, ans);
11         return ans;
12     }
13 
14     private void arrary(int[] nums, int length, int depth, boolean[] used, Stack<Integer> path, List<List<Integer>> ans) {
15         if (depth == length) {
16             ans.add(new ArrayList<>(path));
17             return;
18         }
19 
20         for (int i = 0; i < length; i++) {
21             if (used[i]) continue;
22             //剪枝 去除重复结果
23             //used[i] == used[i - 1] 如果这次选取数字与同深度的上次选取数字一样 则后面排序有可能重复 如Aa... 与 aA...排序结果必然一样
24             //used[i - 1] == false 为了排除不同深度情况下 相同数字的树枝不被误剪 如Aab 在选取Aa时不应该因为Aa相同而剪掉Aab树枝
25             if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false)  continue;
26 
27             used[i] = true;
28             path.push(nums[i]);
29 
30             arrary(nums, length, depth + 1, used, path, ans);
31 
32             used[i] = false;
33             path.pop();
34         }
35     }

详细查看https://leetcode-cn.com/problems/permutations-ii/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liwe-2/

posted @ 2020-07-19 21:16  陈糊糊啊  阅读(68)  评论(0)    收藏  举报