【数据结构C++】哈希表(三)

哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,时间复杂度为O(1);而代价仅仅是消耗比较多的内存。

  • 两数之和: https://leetcode-cn.com/problems/two-sum/
    在这里插入图片描述

    方法二:哈希表
    思路及算法
    创建一个哈希表,对于每一个x,首先查询哈希表中是否存在target-x,然后将x插入到哈希表中,即可保证不会让x 和自己匹配。
    
    class Solution {
    public:
        vector<int> twoSum(vector<int>& nums, int target) {
            unordered_map<int, int> hashtable;   //unordered_map创建一个哈希表
            for (int i = 0; i < nums.size(); ++i) {
                auto it = hashtable.find(target - nums[i]);
    	            //it 表示的是hashtable的第一整个元素;
    				//it->first 表示的是这个元素的key的值;
    				//it->second 表示的是这个元素的value的值。
                if (it != hashtable.end()) {
                    return {it->second, i};          //??? it->second不是指向的是value?
                }
                hashtable[nums[i]] = i;
            }
            return {};
        }
    };
    
    复杂度分析
    时间复杂度:O(N),其中 N 是数组中的元素数量。对于每一个元素 x,我们可以 O(1) 地寻找 target - x。
    空间复杂度:O(N),其中 N 是数组中的元素数量。主要为哈希表的开销。
    
  • 存在重复元素: https://leetcode-cn.com/problems/contains-duplicate/
    在这里插入图片描述

    在这里插入图片描述

    class Solution {
    public:
        bool containsDuplicate(vector<int>& nums) {
            unordered_set<int> s;
            for (int x: nums) {
    			//查找函数 find() 通过给定主键查找元素
    			//如果s.find()要找的值在set中则返回一个指向该值的迭代器,
    			//如果没有找到则返回s.end()。
                if (s.find(x) != s.end()) {
                    return true;
                }
                s.insert(x);
            }
            return false;
        }
    };
    复杂度分析
    时间复杂度:O(N),其中 N 为数组的长度。
    空间复杂度:O(N),其中 N 为数组的长度。
    
  • 最长和谐子序列: https://leetcode-cn.com/problems/longest-harmonious-subsequence/
    在这里插入图片描述

    方法二:哈希表
    思路与算法
    
    遍历数组找出所有的 x 和x+1的出现的次数,用一个哈希映射来存储每个数出现的次数,这样就能在O(1) 的时间内得到x和x+1 出现的次数。
    
    我们首先遍历一遍数组,得到哈希映射。随后遍历哈希映射,设当前遍历到的键值对为(x, value),那么我们就查询x+1 在哈希映射中对应的统计次数,就得到了x和x+1 出现的次数,和谐子序列的长度等于 x 和 x+1 出现的次数之和。
    
    class Solution {
    public:
        int findLHS(vector<int>& nums) {
            unordered_map<int, int> cnt;
            int res = 0;
            for (int num : nums) {
                cnt[num]++;
            }
            for (auto [key, val] : cnt) {
                if (cnt.count(key + 1)) {
                    res = max(res, val + cnt[key + 1]);
                }
            }
            return res;
        }
    };
    
    复杂度分析
    时间复杂度:O(N),其中N为数组的长度。
    空间复杂度:O(N),其中N为数组的长度。数组中最多有N个不同元素,因此哈希表最多存储N个数据。
    
  • 最长连续序列: https://leetcode-cn.com/problems/longest-consecutive-sequence/
    在这里插入图片描述
    在这里插入图片描述

    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            unordered_set<int> num_set;                    //创建一个哈希表
            for (const int& num : nums) {
                num_set.insert(num);                      //去掉重复的值
            }
            int longestStreak = 0;
            for (const int& num : num_set) {
                if (!num_set.count(num - 1)) {       //当存在x-1的数时,则跳过,否则就执行下面当前值加1的操作
                    int currentNum = num;
                    int currentStreak = 1;
    
                    while (num_set.count(currentNum + 1)) { 
                        currentNum += 1;
                        currentStreak += 1;
                    }
                    longestStreak = max(longestStreak, currentStreak);
                }
            }
            return longestStreak;           
        }
    };
    复杂度分析
    时间复杂度:O(n),其中 n 为数组的长度。
    空间复杂度:O(n)。哈希表存储数组中所有的数需要 O(n) 的空间。
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只搬烫手的砖

你的鼓励将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值