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

【leetcode刷题之路】面试经典hot100(1)——哈希+双指针+滑动窗口+子串

文章目录

      • 1 哈希
        • 1.1 【哈希】【模拟】两数之和
        • 1.2 【哈希】【字符串】字母异位词
        • 1.3 【模拟】【哈希】最长连续序列
      • 2 双指针
        • 2.1 【双指针】【数组】移动零
        • 2.2 【双指针】【数组】盛最多水的容器
        • 2.3 【双指针】【数组】三数之和
        • 2.4 【双指针】接雨水
      • 3 滑动窗口
        • 3.1 【滑动窗口】【字符串】无重复字符的最长子串
        • 3.2 【滑动窗口】【哈希】找到字符串中所有字母异位词
      • 4 子串
        • 4.1 【前缀和】和为 K 的子数组
        • 4.2 【滑动窗口】滑动窗口最大值
        • 4.3 【字符串】【滑动窗口】最小覆盖子串

1 哈希

1.1 【哈希】【模拟】两数之和

题目链接:https://leetcode.cn/problems/two-sum/description/?envType=study-plan-v2&envId=top-100-liked

用哈希表解题,当遍历数组元素的过程中,只需要找到target与当前元素的差值是不是在数组中即可,比如:

(1)样例1

设哈希表为ht={ },nums=[2,7,11,15],target=9,开始遍历元素:

  • 第一个元素为2,差值为7,7不在哈希表中,把2和下标加入哈希表,此时ht={2 : 0};
  • 第二个元素为7,差值为2,2在哈希表中,结果为[0,1]。

(2)样例2

设哈希表为ht={ },nums=[3,2,4],target=6,开始遍历元素:

  • 第一个元素为3,差值为3,3不在哈希表中,把3和下标加入哈希表,此时ht={3 : 0};
  • 第二个元素为2,差值为4,4不在哈希表中,把4和下标加入哈希表,此时ht={3 : 0, 4 : 1};
  • 第三个元素为4,差值为2,2在哈希表中,结果为[1,2]。
class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:ht = {}for i,n in enumerate(nums):if target-n in ht:return [ht[target-n],i]ht[n] = i
1.2 【哈希】【字符串】字母异位词

题目链接:https://leetcode.cn/problems/group-anagrams/description/?envType=study-plan-v2&envId=top-100-liked

对每个单词的所有字母进行排序,对于字母异位词的单词,它们排序之后的结果应该是一样的,因为他们的各个字母的次数是一样的,所以基于这个来划分字母异位词。

class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:ht = {}for s in strs:tmp = "".join(sorted(s))if tmp in ht:ht[tmp].append(s)else:ht[tmp] = [s]return list(ht.values())
1.3 【模拟】【哈希】最长连续序列

题目链接:https://leetcode.cn/problems/longest-consecutive-sequence/submissions/552801160/?envType=study-plan-v2&envId=top-100-liked

直接对原数组进行排序,但是要考虑到两种情况:(1)数组为空;(2)数组中有重复元素。

class Solution:def longestConsecutive(self, nums: List[int]) -> int:if len(nums) == 0:return 0max_len,cur = 1,1nums.sort()for i in range(0,len(nums)-1):if nums[i+1] - nums[i] == 1:cur += 1max_len = cur if cur > max_len else max_lenelif nums[i+1] == nums[i]:continueelse:cur = 1return max_len

2 双指针

2.1 【双指针】【数组】移动零

题目链接:https://leetcode.cn/problems/move-zeroes/description/?envType=study-plan-v2&envId=top-100-liked

设置快慢指针,快指针找到第一个非零元素,慢指针找到第一个零元素,交换位置即可。

class Solution:def moveZeroes(self, nums: List[int]) -> None:slow,fast = 0,0while fast < len(nums):while nums[slow] !=0 and slow < len(nums)-1:slow += 1fast += 1while nums[fast] == 0 and  fast < len(nums)-1:fast += 1nums[slow],nums[fast] = nums[fast],nums[slow]slow += 1fast += 1
2.2 【双指针】【数组】盛最多水的容器

题目链接:https://leetcode.cn/problems/container-with-most-water/description/?envType=study-plan-v2&envId=top-100-liked

设置左右指针,每次遍历时容器的体积取决于两边最低的高度是多少,所以每次遍历的时候哪边的高度更小,哪边就向里移动一格。

class Solution:def maxArea(self, height: List[int]) -> int:ans = 0left,right = 0,len(height)-1while left < right:cur = (right-left) * min(height[left],height[right])ans = cur if cur > ans else ansif height[left] < height[right]:left += 1else:right -= 1return ans
2.3 【双指针】【数组】三数之和

题目链接:https://leetcode.cn/problems/3sum/description/?envType=study-plan-v2&envId=top-100-liked

先排序,然后去重,每次固定一个数,在剩下的范围中用双指针找合为0的三元组。

class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:length = len(nums)ans = []if length < 3:return ansnums.sort()for i in range(length):if nums[i] > 0:return ansif i > 0 and nums[i] == nums[i-1]:continueleft = i + 1right = length - 1while left < right:if nums[i] + nums[left] + nums[right] == 0:ans.append([nums[i],nums[left],nums[right]])while left<right and nums[left] == nums[left+1]:left += 1while left<right and nums[right] == nums[right-1]:right -= 1left += 1right -= 1elif nums[i] + nums[left] + nums[right] < 0:left += 1else:right -= 1return ans
2.4 【双指针】接雨水

题目链接:https://leetcode.cn/problems/trapping-rain-water/description/?envType=study-plan-v2&envId=top-100-liked

双指针解决,分别记录左边和右边的最大值,然后依次从两边往中间记录差值,最后差值的和即为接雨水量。

class Solution:def trap(self, height: List[int]) -> int:ans = 0left,right = 0,len(height)-1max_left,max_right = height[left],height[right]while left < right:max_left = max(max_left,height[left])max_right = max(max_right,height[right])if max_left < max_right:ans += max_left - height[left]left += 1else:ans += max_right - height[right]right -= 1return ans 

3 滑动窗口

3.1 【滑动窗口】【字符串】无重复字符的最长子串

题目链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/?envType=study-plan-v2&envId=top-100-liked

设置一个滑动窗口,如果遍历到的字母没有在窗口内出现过,则窗口长度+1,否则把窗口左边的元素剔除,直到窗口内没有重复元素,每次窗口滑动时记录是否为最大值。

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:max_l = 0cur = ""i = 0while i < len(s):if s[i] not in cur:cur += s[i]max_l = max(max_l,len(cur))i += 1else:cur = cur[1:]return max_l
3.2 【滑动窗口】【哈希】找到字符串中所有字母异位词

题目链接:https://leetcode.cn/problems/find-all-anagrams-in-a-string/description/?envType=study-plan-v2&envId=top-100-liked

统计字符串p中字母的出现次数,当滑动窗口移动时,判断窗口内字母的次数和p是否一致,一致的话记录此时的下标。

class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:n, m, res = len(s), len(p), []if n < m: return resp_cnt = [0] * 26s_cnt = [0] * 26for i in range(m):p_cnt[ord(p[i]) - ord('a')] += 1s_cnt[ord(s[i]) - ord('a')] += 1if s_cnt == p_cnt:res.append(0)for i in range(m, n):s_cnt[ord(s[i - m]) - ord('a')] -= 1s_cnt[ord(s[i]) - ord('a')] += 1if s_cnt == p_cnt:res.append(i - m + 1)return res

4 子串

4.1 【前缀和】和为 K 的子数组

题目链接:https://leetcode.cn/problems/subarray-sum-equals-k/description/?envType=study-plan-v2&envId=top-100-liked

利用前缀和的思想,假设目前的前缀和为presum,我只需要找到在这之前前缀和为presum-k的情况一共出现了多少次,作差子数组和就是k。

class Solution:def subarraySum(self, nums: List[int], k: int) -> int:ans = 0presum = collections.defaultdict(int)presum[0] = 1cur_presum = 0for n in nums:cur_presum += nans += presum[cur_presum-k]presum[cur_presum] += 1return ans
4.2 【滑动窗口】滑动窗口最大值

题目链接:https://leetcode.cn/problems/sliding-window-maximum/description/?envType=study-plan-v2&envId=top-100-liked

维护一个单调递减的双端队列,保证队列首元素一直是目前的最大值。

class Solution:def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:ans = []q = deque()for i,x in enumerate(nums):while q and nums[q[-1]] < x:q.pop()q.append(i)if i-q[0] >= k:q.popleft()if i >= k-1:ans.append(nums[q[0]])return ans
4.3 【字符串】【滑动窗口】最小覆盖子串

题目链接:https://leetcode.cn/problems/minimum-window-substring/description/?envType=study-plan-v2&envId=top-100-liked

1.不断增加使滑动窗口增大,直到窗口包含了t的所有元素;

2.不断增加使滑动窗口缩小,将不必要的元素排除在外,直到碰到一个必须包含的元记录此时滑动窗口的长度,并保存最小值;

3.再增加一个位置,这个时候滑动窗口肯定不满足条件了,继续从步骤一开始执行,寻找新的满足条件的滑动窗口。

class Solution:def minWindow(self, s: str, t: str) -> str:s_len, t_len, needCnt = len(s), len(t), len(t)need = collections.defaultdict(int)for c in t:need[c] += 1ans = (0,float('inf'))# 增加右边界使滑窗包含ti = 0for j,c in enumerate(s):if need[c] > 0:needCnt -= 1need[c] -= 1# 收缩左边界直到无法再去掉元素if needCnt == 0:while True:ch = s[i]if need[ch] == 0:breakelse:need[ch] += 1i += 1if j-i < ans[1]-ans[0]:ans = (i,j+1)# i多增加一个位置,准备开始下一次循环need[s[i]] += 1needCnt += 1i += 1return ""if ans[1]>s_len else s[ans[0]:ans[1]]

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • HTMLCSS
  • 面试官:怎样设计一个分布式任务调度平台?
  • 【开源分享】PHP在线提交工单源码|工单管理系统源码 (附源码搭建教程)
  • STM32——外部中断(EXTI)
  • 【云原生】Job一次性任务详解
  • xss漏洞(二,xss靶场搭建以及简单利用)
  • 关于使用webflux开发思考
  • Animate软件基本概念:遮罩层和引导层
  • 【Python】解决Yolov8训练时,“OSError: [WinError 1455] 页面文件太小,无法完成操作”错误
  • [自学记录09*]关于模糊效果降采样优化性能的小实验
  • 【异常】npm install 出错几种解决方案
  • Git 的基本概念和使用方式。
  • 期权价格的奥秘:深入理解影响因素
  • C++入门基础知识(笔记):静态成员函数,所有对象共享同一个函数静态成员函数只能访问成员变量,类外访问不到私有静态成员函数
  • 河南萌新(2024)(河南农业大学)(旅途的终点)
  • ES6指北【2】—— 箭头函数
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • [译]CSS 居中(Center)方法大合集
  • ES2017异步函数现已正式可用
  • java 多线程基础, 我觉得还是有必要看看的
  • Java 网络编程(2):UDP 的使用
  • Java,console输出实时的转向GUI textbox
  • Linux后台研发超实用命令总结
  • Python中eval与exec的使用及区别
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 机器学习 vs. 深度学习
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 王永庆:技术创新改变教育未来
  • 消息队列系列二(IOT中消息队列的应用)
  • 一、python与pycharm的安装
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 最近的计划
  • C# - 为值类型重定义相等性
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • ​【经验分享】微机原理、指令判断、判断指令是否正确判断指令是否正确​
  • ​数据结构之初始二叉树(3)
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • (02)vite环境变量配置
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (办公)springboot配置aop处理请求.
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (蓝桥杯每日一题)love
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (转)程序员技术练级攻略
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .apk 成为历史!
  • .chm格式文件如何阅读
  • .NET Core 成都线下面基会拉开序幕
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .net 受管制代码
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示