哈希
128.最长连续序列
要求复杂度为O(n)的算法, 通过两次遍历实现: 第一次遍历将所有元素插入到哈希表中, 第二次遍历过程中对每个元素n进行处理, 如果哈希表中存在值为n-1的元素, 则说明该元素已经被处理或即将被处理; 若不存在, 就继续查看值为n+1, n+2, n+3…的元素是否存在哈希表中, 这样就可以求出数组中所有连续序列的长度了。
双指针
11. 盛最多水的容器
两个指针从数组的两端开始进行处理, 每次移动指向线高度较小的指针, 因为容器的盛水高度取决于较低的边, 所以选择的这条边无法再和另一边的任何一条线组成盛水更多的容器了。两个指针遍历完数组就可以得到最优的结果了。
接下来思考一下如果两个指针指向线的高度相等的情况下该怎么移动, 我们先猜测随便移动其中一个指针都可以, 为了证明这句话, 我们先讨论它的对立面是否成立, 即不能随便移动其中一个指针; 也即存在一种答案, 必须要且只能使用到这两边中某一条边; 可能会出现这种情况的是, 在这两个指针的范围内, 存在一条更高且不位于这两个指针正中央的边, 但是很明显的是, 及时我们使用了这条更高的边, 围成的容器的容积也不会大于这两条高度相等的边围成的容器容积, 所以上面提出的反面假设是错误的。
15. 三数之和
暴力枚举前两个数字, 最后一个数字如果也适用枚举的话时间复杂度就成了O(N3)O(N^3)O(N3), 这样的算法最多可以处理数据规模为300的问题。所以最后一个数字使用双指针来进行优化: 所以问题的答案就是, 先对数组进行排序, 然后枚举前两个数字, 第三个指针从大到小进行遍历数字, 第三个指针和遍历第二个数字的指针就形成了双指针, 时间复杂度为O(N)O(N)O(N), 再加上外层循环, 总的时间复杂度就变成了O(N2)O(N^2)O(N2)。
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
for (int i = 0; i < nums.size(); ++i) {
if (i && nums[i] == nums[i-1]) continue; // 去重
if(nums[i] > 0) break;
int l = i+1, r = nums.size()-1;
int target;
while(l < r) {
if (l > i + 1) {
while(l < r && nums[l] == nums[l-1]) ++l; // 去重
if (l == r) break;
}
target = -1 * (nums[i] + nums[l]);
if(target < nums[r]) {
--r;
} else if (target == nums[r]) {
res.push_back({nums[i], nums[l], nums[r]});
++l;
} else {
++l;
}
}
}
return res;
}
};
42.接雨水
第nnn个柱子正上方的存水单位数为min(max(height1,height2,...heightn−1),max(heightn+1,heightn+2,.....))−heightn\min(\max(height_1, height_2, ...height_{n-1}), \max(height_{n+1}, height_{n+2}, .....))-height_nmin(max(height1,height2,...heightn−1),max(heightn+1,heightn+2,.....))−heightn
预处理出两个数组就可以了, 可以用双指针来优化空间。
滑动窗口
3.无重复字符的最长字串
枚举所有不重复字符串的开始位置, 由于字符串的开始和结束位置都是单调递增的, 所以使用滑动窗口来解决问题。
438.找到字符串中所有字母易位词
枚举所有的字符串的开始位置, 这题比上一题简单, 字符串的长度是固定的, 窗口大小也是固定的, 扫完整个字符串即可。
本文介绍了几个涉及双指针和哈希技术的IT算法问题,如求最长连续序列、盛最多水的容器、三数之和优化和接雨水问题。通过两次遍历、双指针动态调整和哈希表存储,这些算法在O(n)或O(n^2)复杂度下高效解决字符串和数组相关问题。
&spm=1001.2101.3001.5002&articleId=135896574&d=1&t=3&u=2b8a969e9c61458b97c9c64100b40266)
9万+

被折叠的 条评论
为什么被折叠?



