当前位置: 首页 > news >正文

【LeetCode 热题 100】哈希、双指针、滑动窗口

头像
⭐️个人主页:@小羊
⭐️所属专栏:LeetCode 热题 100

很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~

动图描述

目录

    • 哈希
      • 两数之和
      • 字母异位词分组
      • 最长连续序列
    • 双指针
      • 移动零
      • 盛最多水的容器
      • 三数之和
      • 接雨水
    • 滑动窗口
      • 无重复字符的最长子串
      • 找到字符串中所有字母异位词


LeetCode 热题 100 中大多数题我都在算法专栏中写过解题思路,本篇的存在是为了记录一下刷这些明星题的过程(不记录一下总感觉白刷了🤡),因此题解不是很多(虽然你清楚的知道真正原因是什么),望见谅。

哈希

两数之和

  • 两数之和

在这里插入图片描述

遍历数组,对于当前 nums[i],查哈希表是否存在 target - nums[i],如果存在返回两个数对应的下标,如果不存在则哈希表存储数组元素和其对应的下标。

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

字母异位词分组

  • 字母异位词分组

在这里插入图片描述

遍历字符串数组,得到一个字符串后排序其备份,用哈希表分类存储排序后相同的字符串,最后得到字符串和字符串数组的映射,其中 hash.second 就是我们想要的结果。

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {unordered_map<string, vector<string>> hash;for (auto& s : strs){string tmp = s;sort(tmp.begin(), tmp.end());hash[tmp].push_back(s);}vector<vector<string>> ret;for (auto& e : hash){ret.push_back(e.second);}return ret;}
};

最长连续序列

  • 最长连续序列

在这里插入图片描述

用哈希表存储所有数字,遍历哈希表,找到一段数字连续的左边界,统计右边一共有多长,遍历完哈希表就能找到最长的数字连续序列。

class Solution {
public:int longestConsecutive(vector<int>& nums) {unordered_set<int> hash;for (auto e : nums) hash.insert(e); // 先将所有数字存起来int maxlen = 0;for (auto e : hash){if (!hash.count(e - 1)) // 找到一段连续的左边界{int len = 1;while (hash.count(e + 1)) // 统计右边有多长{len++;e++;}maxlen = max(maxlen, len); // 得出最长长度}}return maxlen;}
};

双指针

移动零

  • 移动零

在这里插入图片描述

让左指针始终指向0,右指针向右遍历数组找非0,找到一个就和左指针交换,这样就可以把0不断推到数组后面。

class Solution {
public:void moveZeroes(vector<int>& nums) {int l = 0, r = 0;while (r < nums.size()){if (nums[r]) swap(nums[l++], nums[r]);r++;}}
};

盛最多水的容器

  • 盛最多水的容器

在这里插入图片描述

当以较小的这条边为基准,另一边不断收缩时,容器宽度不断减小,高度不管怎么样也是不会比当前高度高的,因为容器的高度取决于较小的一条边,所以这条较小的边就不需要作为基准遍历的了。

class Solution {
public:int maxArea(vector<int>& height) {int ret = 0;for (int l = 0, r = height.size() - 1; l < r;){ret = max(ret, (r - l) * min(height[l], height[r]));if (height[l] < height[r]) l++;else r--;}return ret;}
};

三数之和

  • 三数之和

在这里插入图片描述

先对数组进行排序,从左向右或从右向左依次固定一个数,在另一边固定两个指针不断收缩遍历,当三个指针指向的值满足要求时加入到结果中。

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(), nums.end());vector<vector<int>> ret;int n = nums.size() - 1; // 固定一个位置while (n > 1){int l = 0, r = n - 1, target = -nums[n];if (target > 0) break;while (l < r){int sum = nums[l] + nums[r];if (sum < target) l++;else if (sum > target) r--;else{ret.push_back({nums[l], nums[r], -target});l++, r--;while (l < r && nums[l] == nums[l - 1]) l++;while (l < r && nums[r] == nums[r + 1]) r--;}}n--;while (n > 1 && nums[n] == nums[n + 1]) n--;}return ret;}
};

接雨水

  • 接雨水

在这里插入图片描述

从左右两边向中间遍历,假设中间没有柱子,记录最小高度min_h,当前最小高度h,则雨水体积为 v = (h - min_h) * (r - l),然后从小的一边收缩,当遇到柱子时减去该柱子高度和记录的最小高度差值中的较小值。

class Solution {
public:int trap(vector<int>& height) {int l = 0, r = height.size() - 1;int v = 0, min_h = 0;while (l < r){int h = min(height[l], height[r]);if (h > min_h){v += (r - l) * (h - min_h);min_h = h;}if (height[l] < height[r]) v -= min(height[l++], min_h);else v-= min(height[r--], min_h);}return v;}
};

官方题解:

双指针从两边向中间遍历,过程中分别记录左边和右边最大值,哪边小哪边收缩,此刻收缩的这边暂时能接到的雨水为 max_r - height[r] 或 max_l - height[l]。

class Solution {
public:int trap(vector<int>& height) {int l = 0, r = height.size() - 1;int v = 0, max_l = 0, max_r = 0;while (l < r){max_l = max(max_l, height[l]);max_r = max(max_r, height[r]);if (height[l] < height[r]) v += max_l - height[l++];else v += max_r - height[r--];}return v;}
};

滑动窗口

无重复字符的最长子串

  • 无重复字符的最长子串

在这里插入图片描述

class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_set<char> set;int l = 0, r = 0, res = 0;while (r < s.size()){while (set.count(s[r])) set.erase(s[l++]);res = max(res, r - l + 1);set.insert(s[r++]);}return res;}
};

找到字符串中所有字母异位词

  • 找到字符串中所有字母异位词

在这里插入图片描述

class Solution {
public:vector<int> findAnagrams(string s, string p) {int n = p.size();int hash1[26] = {};for (auto ch : p) hash1[ch - 'a']++;int hash2[26] = {};vector<int> res;for (int l = 0, r = 0, cnt = 0; r < s.size(); r++){int in = s[r] - 'a';if (++hash2[in] <= hash1[in]) cnt++;while (r - l + 1 > n){int out = s[l++] - 'a';if (hash2[out]-- <= hash1[out]) cnt--;} if (cnt == n) res.push_back(l);}return res;}
};


本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~

头像
http://www.xdnf.cn/news/65953.html

相关文章:

  • 【Markdown】【HTML】在Markdown中实现康奈尔笔记模式(右侧留白)
  • 算法分析与设计——动态规划复习题(待更新
  • Flutter 状态管理 Riverpod
  • 华为IPD流程变革如何推动组织转型?2025变革路径
  • 从代码实现理解Vision Permutator:WeightedPermuteMLP模型解析
  • Java并发编程-线程池
  • spark–sql项目实验
  • 声学重构+交互创新,特伦斯便携钢琴V30Pro专业演奏的移动化时代
  • 信息收集之hack用的网络空间搜索引擎
  • 文件有几十个T,需要做rag,用ragFlow能否快速落地呢?
  • PCB原理图解析(炸鸡派为例)
  • Google独立站和阿里国际站不是一回事
  • Python爬虫与代理IP:高效抓取数据的实战指南
  • Web开发:ABP框架10——使用数据库存储文件,完成文件的下载和上传
  • 【第四章】19-匹配规则定义
  • GPT-4.1 开启智能时代新纪元
  • 算法之动态规划
  • 第42讲:走进智慧农业的“感知神经系统”——农田遥感 + 边缘计算的融合实践
  • WiFi模块使用AT+lwip上网
  • 苹果开发者账号 3.2(f) 被封排查思路及重生指南
  • 在 Spring Boot 项目中怎么识别和优化慢 SQL ?
  • 每日一题——数据中心网络地址规划
  • 简易版自制RTOS
  • AI律师匹配AI分析法律需求意图并匹配律师
  • 7. 服务通信 ---- 使用自定义srv,服务方和客户方cpp,python文件编写
  • 操作指南:在vue-fastapi-admin上增加新的功能模块
  • 江湖密码术:Rust中的 bcrypt 加密秘籍
  • 算法 | 成长优化算法(Growth Optimizer,GO)原理,公式,应用,算法改进研究综述,matlab代码
  • QLisview 实现model deletage,并且在不需要编辑的情况下自定义UI
  • 【Redis】Jedis与Jedis连接池