【如果笔记对你有帮助,欢迎关注&点赞&收藏,收到正反馈会加快更新!谢谢支持!】
ps:笔记和代码按本人理解整理,重思路
目录
上期笔记
LeetCode HOT100刷题笔记(一):哈希表, 双指针_leetcode刷题笔记模板-CSDN博客
一、滑动窗口
题目8:无重复字符的最长子串
- 题意:找到字符串s中无重复字符的最长子串

- 拆解:
「滑动窗口」一左一右两个指针组成 「代码逻辑」 - 初始化滑动窗口的左右指针在最左端 while 右指针右移【扩大窗口】: while 新字符已在窗口中(重复情况): - 左指针右移【缩小窗口】至无重复 更新最长子串 - 代码:
class Solution: def lengthOfLongestSubstring(self, s: str) -> int: left = 0 right = 0 result = 0 while right < len(s): while left < right and s[right] in s[left: right]: left += 1 result = max(result, right - left + 1) right += 1 return result
题目9:找到字符串中所有字母异位词
438. 找到字符串中所有字母异位词 - 力扣(LeetCode)
- 题意:所有
p的 异位词 的子串,记录子串起始index
- 关键:用Counter()统计 p 和窗口的字符和个数,如果两个Counter相等,则记录结果
- 代码:
class Solution: def findAnagrams(self, s: str, p: str) -> List[int]: n = len(s) m = len(p) Counterp = Counter(p) Counters = Counter() ans = [] if n >= m: for i in range(m-1): Counters[s[i]] += 1 for i in range(m-1, n): Counters[s[i]] += 1 if Counters == Counterp: ans.append(i-m+1) Counters[s[i-m+1]] -= 1 return ans
二、数组
题目10:最大子数组和
- 题意:找到和最大的连续子数组

- 关键:及时丢掉和为负数的连续子数组
- 拆解:
「代码逻辑」 - temp_sum:记录当前子数组的和 for nums中的每个num: - 加到temp_sum中 - 更新最大子数组和 if temp_sum < 0: - 丢掉(即temp_sum置0,不让他拖累后面的结果) - 代码:
class Solution: def maxSubArray(self, nums: List[int]) -> int: sum_ = -inf temp_sum = 0 for i in nums: temp_sum += i sum_ = max(sum_, temp_sum) if temp_sum <= 0: temp_sum = 0 return sum_
题目11:合并区间
- 题意:一个数组里面有多个可能有重叠部分的区间,合并重叠部分,返回合并后的所有区间

- 关键:先通过排序确定一端(如左端),再找可以合并的区间们,确认另一端
- 拆解:
「代码逻辑」 - 根据区间们的左端排序 - ans:记录合并后的区间 for 每个区间: if 当前区间和ans[-1]区间相交【可合并】: - 更新ans[-1]区间右端 else【不可合并】: - ans加入当前区间 - 代码:
class Solution: def merge(self, intervals: List[List[int]]) -> List[List[int]]: intervals.sort(key=lambda p: p[0]) # 按照左端点从小到大排序 ans = [] for p in intervals: if ans and p[0] <= ans[-1][1]: # 可以合并 ans[-1][1] = max(ans[-1][1], p[1]) # 更新右端点最大值 else: # 不相交,无法合并 ans.append(p) # 新的合并区间 return ans
题目12:轮转数组
- 题意:将数组中的元素向右轮转k个位置,要求空间复杂度O(1)

- 关键:用反转数组解决
- 拆解:
「代码逻辑」 - 反转整个数组 - 反转数组前k个[:k] - 反转剩余后面数组[k:] 【得到轮转数组】 - 代码:
class Solution: def rotate(self, nums: List[int], k: int) -> None: """ Do not return anything, modify nums in-place instead. """ k = k % len(nums) def reverse(arr): l = 0 r = len(arr)-1 while l <= r: arr[l], arr[r] = arr[r], arr[l] l += 1 r -= 1 return arr nums = reverse(nums) nums[:k] = reverse(nums[:k]) nums[k:] = reverse(nums[k:])
题目13:除自身以外数组的乘积
238. 除自身以外数组的乘积 - 力扣(LeetCode)
- 题意:返回answer,其中
answer[i]=nums中除nums[i]之外其余各元素的乘积

- 关键:\前缀和\ 和 \后缀和\ 记录乘积
-
拆解:
「代码逻辑」 - pre 前缀和 nums[:i]的乘积 - suff 后缀和 nums[i+1:]的乘积 - answer[i] = nums[:i]的乘积*nums[i+1:]的乘积 = pre[i]*suff[i] 「例子」 nums = [1,2,3,4] pre = [1,1,2,6] suff =[24,12,4,1] answer[1] = pre[1]*suff[1] = 12 -
代码:
「代码逻辑」 - pre 前缀和 nums[:i]的乘积 - suff 后缀和 nums[i+1:]的乘积 - answer[i] = nums[:i]的乘积*nums[i+1:]的乘积 = pre[i]*suff[i] 「例子」 nums = [1,2,3,4] pre = [1,1,2,6] suff =[24,12,4,1] answer[1] = pre[1]*suff[1] = 12
题目14:缺失的第一个正数
- 题意:找到数组中没有出现的最小正整数,要求时间复杂度O(n),只使用O(1)额外空间

- 关键:两遍遍历数组,第一遍让所有所有数组长度范围内的数归位,第二遍找出没出现的最小正整数
- 拆解:
「代码逻辑」 - 第一遍遍历 - 通过【交换】,把数num放到数组中第num个位置 (跳过 <1 或者 >n 的数) - 第二遍遍历 - 看 nums[i] == i+1 是否成立(数num是否在第num个位置) 如果不在就返回结果(说明找到没出现的最小正整数) - 代码:
class Solution: def firstMissingPositive(self, nums: List[int]) -> int: n = len(nums) for i in range(n): while 1 <= nums[i] <= n and nums[nums[i] - 1] != nums[i]: j = nums[i] - 1 nums[i], nums[j] = nums[j], nums[i] for i, num in enumerate(nums): if num != i+1: return i+1 return n+1


:滑动窗口,数组&spm=1001.2101.3001.5002&articleId=148370088&d=1&t=3&u=42fbfc9e3bea459a8c144c59a34a31e3)
3543

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



