例一 最长连续序列
题目描述:
给定一个未排序的整数数组 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;
}
};