哈希表

例一 最长连续序列

原题链接

题目描述:

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例1:

示例2:

 题目分析:

我们可以用一个哈希表来存贮数组中的数,方便每次对一个数的查询。因为一个数字连续序列是不包含重复的数字的,所以直接枚举去重过后的hash数组是不会影响最后的结果的,但去重过的数组长度会更短,因此运行效率也会变得更高。

值得注意的是如果已知有一个 x, x+1, x+2, ...的连续序列,而我们却重新从 x+1,x+2 或者是更后面开始尝试匹配,那么得到的结果肯定不会优于枚举 xx 为起点的答案,因此我们在外层循环的时候碰到这种情况跳过即可。

所以我们检测哈希表内是否存在 x - 1 ,如果有则不用去考虑它,直接跳过。

题解代码:

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> aa;
        int max_len = 0;
        int mmax = 0, zhi;

        for(auto c : nums){
            aa.insert(c);
        }

        for(int i = 0; i < nums.size(); i++){
            if(!aa.count(nums[i] - 1)){
               zhi = nums[i];
               max_len = 1;
            

               while(aa.count(zhi + 1)){
                    max_len ++;

                    zhi ++;
               }
 
               mmax = max(mmax, max_len);
            }
        }

        return mmax;
    }
};

例二  砖墙  

原题链接

题目描述:

你的面前有一堵矩形的、由 n 行砖块组成的砖墙。这些砖块高度相同(也就是一个单位高)但是宽度不同。每一行砖块的宽度之和相等。

你现在要画一条 自顶向下的、穿过 最少 砖块的垂线。如果你画的线只是从砖块的边缘经过,就不算穿过这块砖。你不能沿着墙的两个垂直边缘之一画线,这样显然是没有穿过一块砖的。

给你一个二维数组 wall ,该数组包含这堵墙的相关信息。其中,wall[i] 是一个代表从左至右每块砖的宽度的数组。你需要找出怎样画才能使这条线穿过的砖块数量最少 ,并且返回穿过的砖块数量 。

示例:

题目分析:

要找出怎样画才能使这条线穿过的砖块数量最少,就是求垂线穿过的砖块边缘数量的最大值

我们利用哈希表来存储每一块砖块距离左边界的距离, 即这块砖的右边缘一定有缝隙

我们遍历一遍,找到出现次数(距离左边界的距离)最多的砖块边缘,这就是垂线经过的砖块边缘,而该垂线经过的砖块数量即为砖墙的高度减去该垂线经过的砖块边缘的数量。

题解代码:

class Solution {
public:
    int leastBricks(vector<vector<int>>& wall) {
        unordered_map<int, int> aa;

        for(auto c : wall){
            int n = c.size();
            int sum = 0;

            for(int i = 0; i < n - 1; i ++){
                sum += c[i];

                aa[sum] ++;
            }
        }

        int max_shu = 0;
        for(auto [x, y] : aa){
            max_shu = max(max_shu, y);
        }

        return wall.size() - max_shu;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值