HashMap和HashSet

本文探讨了HashMap和HashSet在解决数组问题中的作用,如寻找数组中和为给定值的两个数、判断数组是否有重复元素、找到最长和谐序列和最长连续序列。使用HashMap和HashSet可以优化算法的时间复杂度,如在寻找数组两数之和问题中,通过HashMap存储元素和索引映射,达到O(N)的时间复杂度。而对于判断数组重复元素、最长和谐序列和最长连续序列,HashSet的使用简化了问题的解决过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hashmap和hashset会自动排序,使用红黑树实现。

1. 数组中两个数的和为给定值

1

可以先对数组进行排序,然后使用双指针方法或者二分查找方法。这样做的时间复杂度为 O(NlogN),空间复杂度为 O(1)。(时间复杂度为什么不是logN平方?)

用 HashMap 存储数组元素和索引的映射,在访问到 nums[i] 时,判断 HashMap 中是否存在 target - nums[i],如果存在说明 target - nums[i] 所在的索引和 i 就是要找的两个数。该方法的时间复杂度为 O(N),空间复杂度为 O(N),使用空间来换取时间。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> m;
        for (int i = 0; i < nums.size(); ++i) {
            if (m.count(target - nums[i])) {
                return {i, m[target - nums[i]]};
            }
            m[nums[i]] = i;
        }
        return {};
    }
};

注意这里不需要两个for循环,不需要先把hashmap的数值先放进去,一边对比一边放就好了。

2. 判断数组是否含有重复元素

217

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_map<int, int> m;
        for (int i = 0; i < nums.size(); ++i) {
            if (m.find(nums[i]) != m.end()) return true;
            ++m[nums[i]];
        }
        return false;
    }
};

这里用了find 改成count也行

if (m.count(nums[i])) return true;
            m[nums[i]]=i;

3. 最长和谐序列

594 和谐序列中最大数和最小数之差正好为 1,应该注意的是序列的元素不一定是数组的连续元素。

class Solution {
public:
    int findLHS(vector<int>& nums) {
        int res = 0;
        map<int, int> m;
        for (int num : nums) ++m[num];
        for (auto a : m) {
            if (m.count(a.first + 1)) {
                res = max(res, m[a.first] + m[a.first + 1]);
            }
        }
        return res;
    }
};

这里的auto a:m到底是什么类型啊??? 不是map<int,int>::iterator类型啊

4. 最长连续序列

128 要求以 O(N) 的时间复杂度求解

Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

hashset还是比较简单的 注意每次要删掉 这样不用重复再计算了

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int res = 0;
        unordered_set<int> s(nums.begin(), nums.end());
        for (int val : nums) {
            if (!s.count(val)) continue;
            s.erase(val);
            int pre = val - 1, next = val + 1;
            while (s.count(pre)) s.erase(pre--);
            while (s.count(next)) s.erase(next++);
            res = max(res, next - pre - 1);
        }
        return res;
    }
};

hashmap的实现还是需要思考的  每次遇到重复的时候不要再计算了 然后每次边界都要更新

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int res = 0;
        unordered_map<int, int> m;
        for (int num : nums) {
            if (m.count(num)) continue;
            int left = m.count(num - 1) ? m[num - 1] : 0;
            int right = m.count(num + 1) ? m[num + 1] : 0;
            int sum = left + right + 1;
            m[num] = sum;
            res = max(res, sum);
            m[num - left] = sum;
            m[num + right] = sum;
        }
        return res;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值