题目:

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

For example,
[1,1,2] have the following unique permutations:
[1,1,2][1,2,1], and [2,1,1].

链接: http://leetcode.com/problems/permutations-ii/

题解:

求全排列,但元素可能有重复。去重复就成为了关键。今天好好思考了一下dfs+回溯,比如1134,最外层就是求出第一个元素,比如 1, 2, 3, 里面的嵌套dfs再负责第二,三,四个元素。 去重复的方法是传递一个visited数组,把排序后相同的元素看成一个cluster,假如nums[i] == nums[i - 1],但i-1没有被访问过,说明整个cluster不被访问,跳过整个cluster。

Time complexity - O(n!), Space Complexity - O(n)。

public class Solution {public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> res = new ArrayList<>();if(nums == null || nums.length == 0)return res;Arrays.sort(nums);ArrayList<Integer> list = new ArrayList<Integer>();boolean[] visited = new boolean[nums.length];dfs(res, list, nums, visited);return res;}private void dfs(List<List<Integer>> res, ArrayList<Integer> list, int[] nums, boolean[] visited) {if(list.size() == nums.length) {res.add(new ArrayList<Integer>(list));return;}for(int i = 0; i < nums.length; i++) {if(visited[i] || (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]))      //skip duplicatescontinue;if(!visited[i]) {visited[i] = true;list.add(nums[i]);dfs(res, list, nums, visited);list.remove(list.size() - 1);visited[i] = false;}}}
}

二刷:

Java:

DFS + Backtracking:

一刷写的一坨屎...这遍依然不清不楚。 主要还是用了Permutation的代码,不同的地方是,我们使用了一个数组 - boolean[] visited。这个数组用来在dfs过程中记录已经访问过的值来避免计算重复。同时我们在dfs和backtracking的时候也要回溯这个数组。 经过上述步骤,我们就可以避免在dfs的时候有重复了。比如输入数组为[1, 1, 1], 则这个最后的结果 {[1, 1, 1]}是在最外层被加入到res中去的。   我们也要注意在遍历数组的时候,假如 visited[i]或者(i > 0 && nums[i] == nums[i - 1] && visited[i - 1]),要continue。

Time Complexity - O(n!), Space Complexity - O(n)

public class Solution {public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> res = new ArrayList<>();if (nums == null || nums.length == 0) {return res;}Arrays.sort(nums);boolean[] visited = new boolean[nums.length];permuteUnique(res, new ArrayList<Integer>(), visited, nums);return res;}private void permuteUnique(List<List<Integer>> res, List<Integer> onePerm, boolean[] visited, int[] nums) {if (onePerm.size() == nums.length) {res.add(new ArrayList<>(onePerm));return;}for (int i = 0; i < nums.length; i++) {if (visited[i] || (i > 0 && nums[i] == nums[i - 1] && visited[i - 1])) {continue;}visited[i] = true;onePerm.add(nums[i]);permuteUnique(res, onePerm, visited, nums); onePerm.remove(onePerm.size() - 1);visited[i] = false;}}
}

Iterative: Using Next Permutation:

我们依然可以使用Permutation I里面使用了求next permutation的代码, 完全搬移,都不用改的。 时间和空间复杂度还需要好好计算一下。这里有点混。

Time Complexity - O(n!), Space Complexity - O(n)

public class Solution {public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> res = new ArrayList<>();if (nums == null || nums.length == 0) {return res;}Arrays.sort(nums);Integer[] numsInt = new Integer[nums.length];for (int i = 0; i < nums.length; i++) {numsInt[i] = nums[i];}res.add(new ArrayList<>(Arrays.asList(numsInt)));while (hasNextPermutation(numsInt)) {res.add(new ArrayList<>(Arrays.asList(numsInt)));}return res;}private boolean hasNextPermutation(Integer[] nums) {for (int i = nums.length - 2; i >= 0; i--) {if (nums[i] < nums[i + 1]) {for (int j = nums.length - 1; j >= i; j--) {if (nums[j] > nums[i]) {swap(nums, i, j);reverse(nums, i + 1, nums.length - 1);return true;}}}}return false;}private void swap(Integer[] nums, int i, int j) {int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}private void reverse(Integer[] nums, int i, int j) {while (i < j) {swap(nums, i++, j--);}}
}

三刷:

使用了和上一题一样的代码,也是next permutation的方法。

Java:

public class Solution {public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> res = new ArrayList<>();if (nums == null || nums.length == 0) return res;Arrays.sort(nums);do {List<Integer> permu = new ArrayList<>();for (int num : nums) permu.add(num);res.add(permu);} while (hasNextPermutation(nums));return res;}private boolean hasNextPermutation(int[] nums) {int len = nums.length;for (int i = len - 2; i >= 0; i--) {if (nums[i] < nums[i + 1]) {for (int j = len - 1; j > i; j--) {if (nums[j] > nums[i]) {swap(nums, i, j);reverse(nums, i + 1, len - 1);return true;}       }}}return false;}private void swap(int[] nums, int i, int j) {int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}private void reverse(int[] nums, int i, int j) {while (i < j) swap(nums, i++, j--);}
}

Reference:

http://www.cnblogs.com/springfor/p/3898447.html

https://leetcode.com/discuss/25279/a-simple-c-solution-in-only-20-lines

https://leetcode.com/discuss/10609/a-non-recursive-c-implementation-with-o-1-space-cost

https://leetcode.com/discuss/18482/share-my-recursive-solution

https://leetcode.com/discuss/77245/line-python-solution-with-line-handle-duplication-beat-others

https://leetcode.com/discuss/62272/ac-python-clean-solution-108-ms

https://leetcode.com/discuss/55350/short-and-clean-java-solution

47. Permutations II 1相关推荐

  1. 【数字全排列】LeetCode 47. Permutations II

    LeetCode 47. Permutations II Solution1:我的答案 笨蛋方法:和第46题的思路差不多,把vector换成了set就OK啦~~~ class Solution { p ...

  2. 47. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  3. LeetCode 47. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  4. [LeetCode] Permutations II 全排列之二

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  5. LeetCode:Permutations, Permutations II(求全排列)

    Permutations Given a collection of numbers, return all possible permutations. For example,  [1,2,3]  ...

  6. [LeetCode]47. 全排列 II

    47. 全排列 II 难度中等761收藏分享切换为英文接收动态反馈 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列. 示例 1: 输入:nums = [1,1,2] 输出 ...

  7. LeetCode 47. 全排列 II【数组,回溯算法,排序去重】

    47. 全排列 II 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列. 示例 1: 输入:nums = [1,1,2] 输出: [[1,1,2], [1,2,1], [2 ...

  8. 46. 全排列 47. 全排列 II

    46. 全排列 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 .你可以 按任意顺序 返回答案. 示例 1: 输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2 ...

  9. Leetcode: Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

最新文章

  1. 首届“陇剑杯”网络安全大赛线上赛圆满结束
  2. python中matplotlib条形图数值大的在最底层显示_如何使用python的matplotlib模块绘制水平条形图...
  3. linux卸载keystone服务,关于linux下卸载apache后安装apache
  4. jquery总结_代码收藏
  5. 简单JS实现对表的行的增删
  6. HugeGraph 图数据库常见问题汇总
  7. 11.22Daily Scrum(2)
  8. java super关键字_Java入门(二)下
  9. python3连接MSSQL数据库 中文乱码怎么解决?
  10. 安装linux版qq,安装二进制包编译器,安装mysql-5.6.11,删除已安装或安装失败的mysql-5.6.11,简单mysql练习题...
  11. 《信号与系统学习笔记》—周期信号的博里叶级数表示(二)
  12. python如何确定拐点_如何在嘈杂的曲线中找到拐点?
  13. AI经典书单:入门人工智能该读哪些书?
  14. 关于车上那几块屏幕的一点思考
  15. PostgreSQL的学习心得和知识总结(八十三)|词法级自上而下完美实现Oracle数据库的 q转义 的实现方案
  16. 1.1 机器学习与Python
  17. 应届生昆山offer和上海户口offer要如何选择?
  18. Apollo6.0代码Lattice算法详解——Part5: 生成横纵向轨迹
  19. matlab求微分方程的初值问题,Matlab 解常微分方程的初值问题.doc
  20. 蓝桥 贪吃的大嘴(Java)

热门文章

  1. python3下载教程-Python3 教程
  2. github打开出错
  3. codeforces C Deletion of Repeats(hash)
  4. Create React App使用
  5. BILIBILI 高并发实时弹幕系统的实战之路 | 架构师实践日
  6. LeetCode Count and Say
  7. 监听端口的非阻塞性不具有继承性
  8. @总结 - 6@ 后缀自动机
  9. MySql技巧个人笔记
  10. (转)【javascript基础】原型与原型链