语法总结
- unorder_map构造时,key会用到hash,不是标准库类型需要自定义hash函数,array<int, nums>不在默认中吗?
- push_back( )、insert( )、emplace_back( )区别?
- 声明std::array时需要声明长度,语法为array<int, 26> flag、赋值全为0、权威’a’、 fill函数(fill函数是否都可以用?)。
- map的遍历、赋值方式、 map[key].emplace_back(str) (太牛了);
map的遍历方式 1
for(const auto& pair : map){
cout << "key: " << pair->first << "val: " << pair->second << endl;
}
map的遍历方式 2
for(const auto& i){
cout << "key: " << pair->first << "val: " << pair->second << endl;
}
- array<char, n> 转string时,用到了string的构造函数,需要array<char, n>.data()和array<char, n>.length(), 没有length()会报错
// Char 20: AddressSanitizer: stack-buffer-overflow on address 0x7f8e44d000da at pc 0x557b458bc4d9 bp 0x7ffc2573b0f0 sp 0x7ffc2573a8b8
why? - int 和 char 的相互转换,可以直接转换,int 10 -> char 变成ASC码为10的char字符。
- sort()的使用,sort()对任何容器都可以用吗?map啥的等非链式结构。
思路归纳
模式识别:一旦需要根据特征进行归类,就应该使用散列表。该种特征作为散列表的key。
时间复杂度太高… 高在哪里?
class Solution {
public:
void Myhash(const string &s, array<int, 26> &flag){
int temp;
for(int k = 0; k < s.length(); k++){
temp = s[k] - 'a';
flag[temp]++;
}
}
vector<vector<string>> groupAnagrams(vector<string>& strs) {
array<int, 26> flag = {0};
array<int, 26> current_flag = {0};
vector<vector<string>> result;
for(int i = 0; i < strs.size(); i++){
//遍历strs中的每个string,判断strs[i]是否属于某个已存在的数组
bool a = true;
Myhash(strs[i], current_flag);
for(int j = 0; j < result.size(); j++){
Myhash(result[j][0], flag);
if(current_flag == flag){
// 如果strs[i]属于已存在的数组,直接将它push_back
result[j].push_back(strs[i]);
a = false;
}
flag = {0};
}
// 如果strs[i]不属于已存在的数组,则新建一个vector<string>对象,并插入result中
// 初始化时还必须有长度1 ....
if(a){
vector<string> new_group(1, strs[i]);
result.push_back(new_group);
}
current_flag = {0};
}
return result;
}
};
正确写法 1
使用排序后的string元素作为key
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs){
unordered_map<string, vector<string>> map;
for(string str : strs){
string key = str;
sort(key.begin(), key.end());
// 这一句话完成了两项赋值
// 还能这样写woc...
// 如果分开了先对map赋值,再对map中val vec<string>复制...
map[key].emplace_back(str);
}
vector<vector<string>> ans;
// 新版本for循环遍历map
// pair的基基本用法。
for(const auto& pair : map){
ans.emplace_back(pair.second);
}
return ans;
}
};
正确写法 2
使用记录string元素中出字母次数的长度为26的数组作为key
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs){
// 这种写法,用array<int, 26>当key,但是由于unordered_map,没有定义与其有关的hash函数,所以直接写会编译错误
// 两种解决方法:
// 1. 跟官方标准答案一样,自定义一个和array<int, 26>有关的hash。
// 2. 跟下面的答案一样,声明key为string类型,在为map插入key时,将array<int, 26>转换成string
// unordered_map<array<int, 26>, vector<string>> map;
unordered_map<string, vector<string>> map;
for(string str : strs){
// string key = str;
// sort(key.begin(), key.end());
// 这一句话完成了两项赋值
// 还能这样写woc...
// 如果分开了先对map赋值,再对map中val vec<string>复制...
// map[key].emplace_back(str);
array<char, 26> count = {0};
// fill(count.begin(), count.end(), 'a');
for(int i = 0; i < str.length(); i++){
count[str[i] - 'a']++;
}
string count_str(count.data(), count.size());
// string count_str(count.data());
// array<char> 转 string 的时候要跟上 array<char>.size().
// Char 20: AddressSanitizer: stack-buffer-overflow on address 0x7f8e44d000da at pc 0x557b458bc4d9 bp 0x7ffc2573b0f0 sp 0x7ffc2573a8b8
map[count_str].emplace_back(str);
}
vector<vector<string>> ans;
// 新版本for循环遍历map
// pair的基基本用法。
for(const auto& pair : map){
ans.emplace_back(pair.second);
}
return ans;
}
};