算法-unordered_map哈希查找

使用unordered_map的原因:

        key可以无序,效率更高.

        底层实现为哈希表,查找效率和增删效率的时间复杂度低.

key存数组元素的值,value存对应元素的下标

题目链接:

1.两数之和

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的形式都行.

题目链接:

49.字母异位词分组

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",就是相同的了,这时候就可以把他们组合在一起.

128.最长连续序列

本题所用哈希表: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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值