参考:两数之和 三数之和【基础算法精讲 01】_哔哩哔哩_bilibili
ps:笔记按本人理解整理,重思路
【如果笔记对你有帮助,欢迎关注&点赞&收藏,收到正反馈会加快更新!谢谢支持!】
题目1: 两数之和 II - 输入有序数组
167. 两数之和 II - 输入有序数组 - 力扣(LeetCode)
- 思路:数组往左递增,往右递减;两数 → 双指针表示
- 拆解:
- 初始化:左指针 → 最小值(左端);右指针 → 最大值(右端)
- numbers[left] + numbers[right] > target: 右指针向左移 → 两数之和变小
numbers[left] + numbers[right] < target: 左指针向右移 → 两数之和变大
- 代码:
class Solution: def twoSum(self, numbers: List[int], target: int) -> List[int]: left = 0 right = len(numbers) - 1 while left < right: sum_ = numbers[left] + numbers[right] if sum_ == target: return [left+1, right+1] elif sum_ > target: right -= 1 else: left += 1
题目2: 三数之和
- 思路:变有序数组 → 拆成两数之和问题 → 去重
- 变化:要找出所有的三数之和,唯一解 → 所有解
- 拆解:
- 先sort成有序数组(有序时指针的移动才会有意义)
- 三数之和 → 两数之和【A+B+C=0,固定A → B+C=-A(其中C>B>A,避免重复)】
- 去重1:固定A时,重复的A只算一次
- 【变化】算两数之和时要找出所有解:sum_ == target 时,左指针右移,右指针左移,并且跳过重复数字(去重2)
- 代码:
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: result = [] nums = sorted(nums) for i in range(len(nums)-2): # 注释中 A=nums[i] if i > 0 and nums[i] == nums[i-1]: # 固定A时的重复情况 continue if nums[i] > 0: # 因为 C>B>A>0,三数之和不可能为0,直接结束 return result # 开始两数之和 left = i+1 right = len(nums)-1 while left < right: sum_ = nums[i]+nums[left]+nums[right] if sum_ > 0: right -= 1 elif sum_ < 0: left += 1 else: result.append([nums[i], nums[left], nums[right]]) # 因为这题可能有多个答案,要找出所有答案 # 找到一个解之后怎么找下一个解:跳过重复数字 → 左右指针同时右移和左移 while left < right and nums[left] == nums[left+1]: # 跳过重复数字 left += 1 while left < right and nums[left] == nums[right-1]: # 跳过重复数字 right -= 1 left += 1 right -= 1 return result
往期笔记:
二分查找学习笔记(一):在排序数组中查找元素的第一个和最后一个位置-CSDN博客
二分查找学习笔记(二):正整数和负整数的最大计数,咒语和药水的成功对数,H 指数 II-CSDN博客
二分查找学习笔记(三):寻找峰值,寻找峰值II-CSDN博客
二分查找学习笔记(四):寻找旋转排序数组中的最小值I & II,搜索旋转排序数组-CSDN博客
:两数之和 II ,三数之和&spm=1001.2101.3001.5002&articleId=145172743&d=1&t=3&u=670020cf5fb743049729d84be238de88)

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



