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

Example:

Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]

法1.递归。swap.回溯。唯一要多做的就是去重。用unordered_set的insert就行。因为用的是hash的无序集合,所以要用std::sort重排一下。

细节:string 的长度 .size()或者.length()都是一样的。

而strlen(const char *)  形参类型是常量字符指针。

class Solution {
public:
vector<string> Permutation(string str)
{
vector<string> ret;
if(str.size()==0) return ret;
Helper(str, 0,ret); unordered_set<string> myset;//去重
ret = Helper2(ret,myset);
return ret;
} //fixed:[0:start-1]
//result:[start:size()-1]
void Helper(string str,int start,vector<string> &ret)
{
if(start==str.size())//string::size()和string::length()一样的。
{
ret.push_back(str);
return;
}
//[start:size()-1]全排列
for(int i =start ;i<str.size();i++)//
{
swap(str[i],str[start]);
Helper(str, start+1,ret);
swap(str[i],str[start]);
}
} vector<string> Helper2(vector<string> ret,unordered_set<string> &myset)
{
for(auto str:ret)
{
myset.insert(str);
}
vector<string> rets;
for(auto str:myset)
{
rets.push_back(str);
}
sort(rets.begin(),rets.end());
return rets;
}
};

法2.递归。更简单的递归。用红黑树实现的set,是本身就已经排序好的有序集合。

细节。 return vector<vector<int>>(ret.begin(),ret.end());这种写法是对的。在leetcode里面只能用有序集合。否则用unordered_set报错:需要实现特定的hash函数。

error: static assertion failed: hash function must be invocable with an argument of key type
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
unordered_set<vector<int>> ret;
if(nums.empty())
return vector<vector<int>>();
Helper(nums,0,ret);
return vector<vector<int>>(ret.begin(),ret.end()); } void Helper(vector<int> nums,int start,unordered_set<vector<int>> &ret)
{
if(start==nums.size())
{
ret.insert(nums);
return;
}
for(int i=start;i<nums.size();i++)
{
swap(nums[i],nums[start]);
Helper(nums,start+1,ret);
swap(nums[i],nums[start]);
}
}
};

unordered_set容器中的key是无序的,就不满足上述递增要求了,而set能保证容器中key有序。

set能保持有序,因为底层基于RB-Tree,天然的有序结构,而unordered_set底层则是hashtable。

记得当时用unordered_set做class或者struct的容器时就得实现特定的hash函数,当元素较少、hash bucket很多的时候,负载因子很小,发生冲突的概率很小,这样保证了unordered_set的查找效率。因此,在负载因子大于某个常数(1或者0.75)就需要对哈希表进行扩容。

下面一个测试看出在使用上set和unordered_set区别

int main()
{
set<int>s1;
unordered_set<int>s2;
s1.insert(4);
s1.insert(2);
s1.insert(3);
s1.insert(1);
s2.insert(4);
s2.insert(2);
s2.insert(3);
s2.insert(1);
for (auto it = s1.begin(); it != s1.end(); ++it)
cout << *it << " ";
cout << endl;
for (auto it = s2.begin(); it != s2.end(); ++it)
cout << *it << " ";
cout << endl;
}

输出:

1 2 3 4

4 2 3 1


更多做法

LeetCode47.Permutations II(剑指offer38-1)的更多相关文章

  1. leetcode47. Permutations II

    leetcode47. Permutations II 题意: 给定可能包含重复的数字的集合,返回所有可能的唯一排列. 思路: 这题全排列两种写法. 用hash表记录已经visit的数字,虽然看起来很 ...

  2. 【LeetCode】137. 只出现一次的数字 II(剑指offer 56-II)

    137. 只出现一次的数字 II(剑指offer 56-II) 知识点:哈希表:位运算 题目描述 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 .请你找出并返回 ...

  3. 【算法训练营day8】LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58-II. 左旋转字符串

    [算法训练营day8]LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58- ...

  4. leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点)

    203题是在链表中删除一个固定的值,83题是在链表中删除重复的数值,但要保留一个:82也是删除重复的数值,但重复的都删除,不保留. 比如[1.2.2.3],83题要求的结果是[1.2.3],82题要求 ...

  5. 剑指Offer38 数组所有数字出现两次,只有两个出现了一次,找出这两个数字

    /************************************************************************* > File Name: 38_Number ...

  6. 154. Find Minimum in Rotated Sorted Array II(剑指offer)

    Follow up for "Find Minimum in Rotated Sorted Array":What if duplicates are allowed? Would ...

  7. 剑指offer--38.左旋转字符串

    时间限制:1秒 空间限制:32768K 热度指数:173814 本题知识点: 字符串 题目描述 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果. ...

  8. 剑指offer38 数字在排序数组中出现的次数

    这种方法没用迭代,而是使用了循环的方式 class Solution { public: int GetNumberOfK(vector<int> data ,int k) { if(da ...

  9. 剑指Offer-38.平衡二叉树(C++/Java)

    题目: 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 分析: 可以从根节点开始遍历每一个节点,求得节点左右子树的最大高度,判断是不是平衡二叉树.这样做的问题在于会重复遍历节点,造成不必要的浪费. 所 ...

随机推荐

  1. 转:99%的人都理解错了HTTP中GET与POST的区别

    原贴来自:http://www.techweb.com.cn/network/system/2016-10-11/2407736.shtml GET和POST是HTTP请求的两种基本方法,要说它们的区 ...

  2. (转)shell解析命令行的过程以及eval命令

    shell解析命令行的过程以及eval命令   本文说明的是一条linux命令在执行时大致要经过哪些过程?以及这些过程的大致顺序. 1.1 shell解析命令行 shell读取和执行命令时的大致操作过 ...

  3. 案例52-crm练习新增客户中加入文件上传功能(struts2文件上传)

    1 jsp/customer/add.jsp 完整代码: <%@ page language="java" contentType="text/html; char ...

  4. a :hover 和a:hover 区别

    article a :hover {  color: red;} 上面表示 article 内所有a 标签的所有子标签在hover时是红色 article a:hover {  color: red; ...

  5. 但是你没有【But you didn't.】【by Anonymous】

    作者是一位普通的美国妇女,她的丈夫在女儿4岁时应征入伍去了越南战场,从此她便和女儿相依为命.后来,她的丈夫.孩子的爸爸不幸阵亡.她终身守寡,直至年老病逝.她女儿在整理遗物时发现了母亲当年写给父亲的这首 ...

  6. TP扩展Xxtea.class.php加密解密函数用法

    http://www.coolcode.org/?action=show&id=128这里可以查到一个相关文章. 附上xiunobbs里的代码,自己加了点注释,欢迎大牛批评指正 //将数值数组 ...

  7. python 在windows下监听键盘按键

    python 在windows下监听键盘按键 使用到的库 ctypes(通过ctypes来调用Win32API, 主要就是调用钩子函数) 使用的Win32API SetWindowsHookEx(), ...

  8. System.Net.Mail

    System.Net.Mail命名空间包含用于将电子邮件发送到简单邮件传输协议(SMTP)服务器进行传送的类. 在此命名空间中,有两个很重要的类:  MailMessage 表示可以使用SmtpCli ...

  9. 关于 header()前面 为什么不能有任何输出的问题

    之前有个问题就是在header () 之前输出,并没有任何报错信息. header() 官网定义必须在任何实际输出之前调用,不管是普通的HTML标签,还是文件或PHP输出的空行,空格.在测试的时候发现 ...

  10. Git学习笔记day01 从GitHub克隆版本库

    本期Git教程将会带您进入Git的世界,这是您使用分布版本控制工具Git的开端,祝您学习顺利! 步骤一  在Linux系统中下载Git 如果是Ubuntu系统,在shell中输入指令 sudo apt ...