使用unordered_map的原因:
key可以无序,效率更高.
底层实现为哈希表,查找效率和增删效率的时间复杂度低.
key存数组元素的值,value存对应元素的下标
题目链接:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> m;
for(int i = 0;i<nums.size();i++)
{
auto iterator = m.find(target - nums[i]);
if(iterator != m.end())
return {iterator->second,i};//也可创建vector数组来保存
m.insert({nums[i],i});
//m[nums[i]] = i;//也可
}
return { };
}
};
做题思路:创建一个map容器m
使用C++11新特性auto iterator代替map<int,int>::iterator 写法更简洁.
map::find()函数的作用是查找容器中对应的key并且返回对应的迭代器.
auto iterator = m.find(target - nums[i]);
①条件判断为真则找到了容器中对应元素的key值,这时候可以直接返回,即
return {iterator->second,i};//也可创建vector数组来保存
这是初始化列表方法,不用创建出相对应的vector对象;
②条件判断为假则将此时循环遍历的元素和对应的下标加入进map容器,即
m.insert({nums[i],i});
//m[nums[i]] = i;//也可
insert()函数的使用之一:形参使用键值对的类型,即pair<int,int>类型.
或者用map[key] = value的形式都行.
题目链接:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;//结果字符串数组
//map容器,key-string,value-string数组
//key对应排完序的字符串,value对应有相同字母个数的同类型字符串
unordered_map<string,vector<string>> m;
for(int i = 0;i<strs.size();i++)
{
string str = strs[i];//str用于排序
sort(str.begin(),str.end());//排序算法sort
m[str].push_back(strs[i]);//key-m[str],将strs[i]插入key对应的字符串数组
}
for(auto it = m.begin();it != m.end(); it++)//将map容器的元素转为vector容器的元素
{
res.push_back(it->second);
}
return res;
}
};
思路:因为都是小写字母,分别对数组中的每个元素进行排序,比如"eat","tea"排序后就是"aet","aet",就是相同的了,这时候就可以把他们组合在一起.
本题所用哈希表:unordered_set容器.
原因:这一题不用查找键值对的关系,unordered_set容器要求容器内元素无重复,且无序,查找和增删的效率很高O(1).
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
//使用初始化列表的方法初始化set容器
//unordered_set<int> s(nums.begin(),nums.end());
unordered_set<int> s;
for(int i = 0;i<nums.size();i++)
{
s.insert(nums[i]);//将nums数组中的元素插入到s中
}
int y,ans = 0;//定义y为从x开始连续递增后的最大值.
for(auto x : s){
if(s.contains(x-1)) continue;//如果x不是最小值,而x-1是,则跳过
//x此时是最小值,开始递增(while内进行)
y = x;
while(s.contains(y+1)) y++;
//找到递增的最大值y后就是答案了.
ans = max(ans,y-x+1);
}
return ans;
}
};
时间复杂度:用两层循环,外层for,内层while,容器内每个元素至多被遍历2遍,所以时间复杂度可以打到O(n).
主要思路:使用for循环遍历容器内的每个元素,对于每个元素要求不是连续递增中最小的数
不是连续递增中最小的数:例如题中的数据样本
for循环第一个遍历的元素是100,则判断容器内100-1是否存在
if(s.contains(x-1)) continue;//如果x不是最小值,而x-1是,则跳过
,不存在则100是连续递增的最小值,存在则跳过.
100跳过
200跳过
1发现是最小的,因为0不存在,则从1开始进入while循环找.最终y停止递增在4.