7-28-8.7计划:每天两题练手,剩下时间去补充一些其他知识
今日题目:
1、颠倒字符的组; tag:哈希表|字符串
2、排列II; tag:回溯
今日摘录:
我感到难过,不是因为你欺骗了我,而是因为我再也不能相信你了。
——尼采
49. Group Anagrams | Difficulty: Medium
Given an array of strings, group anagrams together.
For example, given: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Return:
[
[“ate”, “eat”,”tea”],
[“nat”,”tan”],
[“bat”]
]
tag:哈希表|字符串
题意:将所有字母颠倒的字符串分组,ie,所有字符相同位置不同的为一组。
思路:
1、如何分组呢?创建一个map,key为排序之后的字符串,value为原字符串,那么只需要将排序之后的相同的字符串的原来值加入map,就能达到我们的需求。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
if(strs.size()==0) return res;
unordered_map<string,multiset<string> > mp;
for (string s :strs)
{
string t = s;
sort(t.begin(),t.end());
mp[t].insert(s);
}
for(auto i : mp)
{
vector<string> tmp(i.second.begin(),i.second.end());
res.push_back(tmp);
}
return res;
}
};
结果:80ms
2、上述方法的排序直接用默认排序,考虑对此做一些优化,那么这里有什么特点呢?字符串的一共可能性也就26个字母,完全可以利用桶排序将时间优化至O(N)
class Solution {
public:
string bucketSort(string str)
{
int a[26] = {0};
int len = str.size();
for(auto s : str)
{
a[s-'a']++;
}
string t(len,'a');
int n=0;
for(int i=0;i<26;i++)
{
for(int j=0;j<a[i];j++)
{
t[n++] +=i;
}
}
return t;
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
if(strs.size()==0) return res;
unordered_map<string,multiset<string> > mp;
for (string s :strs)
{
string t = bucketSort(s);
mp[t].insert(s);
}
for(auto i : mp)
{
vector<string> tmp(i.second.begin(),i.second.end());
res.push_back(tmp);
}
return res;
}
};
结果:76ms
47. Permutations II | Difficulty: Medium
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],
[2,1,1]
]
相关题目:Permutations
tag:回溯
题意:求一个可能有重复元素的数组的所有可能组合
思路:
1、再最后判断结果的时候用一个集合
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int> >res;
set<vector<int> > ms;
dfs(nums,0,ms);
for(auto i : ms)
res.push_back(i);
return res;
}
void dfs(vector<int>&nums,int start,set<vector<int> >&ms)
{
if(start>=nums.size() && ms.count(nums)==0)
{
ms.insert(nums);
return;
}
for(int i=start;i<nums.size();i++)
{
swap(nums[i],nums[start]);
dfs(nums,start+1,ms);
swap(nums[i],nums[start]);
}
}
};
结果: Time Limit Exceeded
果然超时了
2、不太好描述,在纸上去模拟一遍[1,1,2,2]情况应该就能有一些体会。
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int> >res;
dfs(nums,0,res);
return res;
}
void dfs(vector<int>nums,int start,vector<vector<int> >&res)
{
if(start>=nums.size()-1)
{
res.push_back(nums);
return;
}
for(int i=start;i<nums.size();i++)
{
if(i!=start && nums[i]==nums[start]) continue;
swap(nums[i],nums[start]);
dfs(nums,start+1,res);
}
}
};
结果:36ms