全排列 II

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

示例说明请见LeetCode官网。

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/permutations-ii/

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一:穷举法
  • 首先,构造一棵多叉树MultiTree,该多叉树有以下几个属性,used表示当前路径已经走过的数组的位置,paths表示当前路径中的数字。
  • 然后声明一个队列queue,队列的元素就是MultiTree,首先将nums中不同的数字出初始化成路径的第一个数字,然后加入到队列中(需要同时初始化used和paths)。
  • 然后遍历队列queue,按照类似的方式将数组nums中没用到的数字加入到当前路径中(需要判断重复数字)。
  • 直到队列中每一条路径的长度都和nums的长度一样,即已将所有的数字加入到路径中。
  • 最后,返回队列中的所有的路径paths。

说明:其实本来想构造一棵多叉树,所有叶子节点到根节点的路径即为所有的路径排列,后来没用到,所以没有构造树的父子关系 。

import java.util.*;

public class LeetCode_047 {

    /**
* 构造一棵多叉树
*/
static class MultiTree {
// 当前的值
public Integer val; public MultiTree parent; // 当前路径已经走过的数组的位置
public List<Integer> used; // 当前路径中的数字
public List<Integer> paths; public MultiTree(Integer val) {
this.val = val;
used = new ArrayList<>();
paths = new ArrayList<>();
}
} public static List<List<Integer>> permuteUnique(int[] nums) {
Queue<MultiTree> queue = new LinkedList<>();
Arrays.sort(nums);
int curNum = nums[0];
// 第一条路径
MultiTree first = new MultiTree(nums[0]);
first.paths.add(nums[0]);
first.used.add(0);
queue.add(first);
// 其他路径
for (int i = 1; i < nums.length; i++) {
if (nums[i] != curNum) {
MultiTree next = new MultiTree(nums[i]);
next.paths.add(nums[i]);
next.used.add(i);
queue.add(next);
curNum = nums[i];
}
} int length = 1; while (length < nums.length) {
int count = queue.size();
while (count > 0) {
MultiTree curNode = queue.poll();
int firstNum = -1, firstNumIndex = -1;
// 找到第一个已有路径没经过的数
for (int i = 0; i < nums.length; i++) {
if (!curNode.used.contains(i)) {
firstNum = nums[i];
firstNumIndex = i;
MultiTree firstTree = new MultiTree(nums[i]);
firstTree.paths.addAll(curNode.paths);
firstTree.paths.add(firstNum);
firstTree.used.addAll(curNode.used);
firstTree.used.add(firstNumIndex);
queue.add(firstTree);
break;
}
} // 将其他不同的数也添加到新的路径
for (int i = firstNumIndex + 1; i < nums.length; i++) {
if (!curNode.used.contains(i) && nums[i] != firstNum) {
MultiTree otherTree = new MultiTree(nums[i]);
otherTree.paths.addAll(curNode.paths);
otherTree.paths.add(nums[i]);
otherTree.used.addAll(curNode.used);
otherTree.used.add(i);
queue.add(otherTree);
firstNum = nums[i];
}
}
count--;
}
length++;
} List<List<Integer>> result = new ArrayList<>();
while (!queue.isEmpty()) {
result.add(queue.poll().paths);
}
return result;
} public static void main(String[] args) {
int[] nums = new int[]{1, 1, 2};
for (List<Integer> integers : permuteUnique(nums)) {
for (Integer integer : integers) {
System.out.print(integer + " ");
}
System.out.println();
}
}
}

【每日寄语】 愿太阳的光辉始终洒在你心上。愿所有的不愉快,苦尽甘来。愿每个脆弱的人都能得到善待。愿现实有光,世界有暖。

最新文章

  1. InstallShield2013 error 6109
  2. js构建ui的统一异常处理方案(四)
  3. 【网络】VPN
  4. 设置html的div中背景图片长宽
  5. Spring-MVC流程图
  6. unity, 在OnDisable里一定要将Cloth禁掉
  7. 使用Qpython3制作老版天翼飞TP路由器拨号脚本
  8. 调整Windows8允许多用户登录
  9. GOPS 2016全球运维大会 • 北京站概况
  10. [LeetCode] Beautiful Arrangement 优美排列
  11. springAOP之代理
  12. 18.JAVA经典编程题(50题及答案)
  13. python 3.3.2报错:No module named &#39;urllib2&#39;
  14. Android学习笔记七:五大存储
  15. ALGO-2_蓝桥杯_算法训练_最大最小公倍数
  16. I - Matches Game(异或运算符的使用)
  17. 【每日scrum】第一次冲刺day5
  18. IO流-批量修改文件名称案例
  19. Command 命令模式 MD
  20. Azure Nosql

热门文章

  1. Java架构系列问题合集-目录
  2. 「 MySQL高级篇 」MySQL索引原理,设计原则
  3. SqlServer基础语法
  4. java中构造函数和一般函数的区别
  5. Android 四种方法写按钮点击事件
  6. linux 设置connect 超时
  7. centOs编译安装php7.2支持微擎php扩展
  8. shell脚本之数组基本操作及排序
  9. JS IndexOf移除符合规则的一项
  10. mybatis的一对多(collection)