音乐
暂未播放
LeetCode | 双指针
分类:双指针 / 总结
讲解#
双指针题目的核心是:用两个指针描述当前正在处理的位置或范围,然后根据规则移动指针。
移动零 的 left 和 right 一开始都在数组最左侧。right 不断向右扫描数组;当 right 看到非零数时,就把它交换到 left 指向的位置,然后 left 向右移动。最后数组前面是所有非零数,后面是所有 0。
盛最多水的容器 的 left 一开始在最左侧,right 一开始在最右侧。两个指针夹住一个容器,计算当前面积后,移动较短的那一边;如果右边更短就移动 right,如果左边更短就移动 left。最后返回最大面积。
三数之和 先排序并固定第一个数 nums[i],然后让 left 从 i + 1 开始,right 从数组最右侧开始,在右侧区间里找另外两个数。如果三数之和偏小,就移动 left;如果三数之和偏大,就移动 right;如果等于 0,就记录答案并同时移动两个指针。最后返回所有不重复的三元组。
接雨水 的 left 一开始在最左侧,right 一开始在最右侧,同时维护 left_max 和 right_max。如果左边高度更低,就结算 left 位置能接的水,然后移动 left;否则结算 right 位置能接的水,然后移动 right。最后返回总水量。
最长回文子串 的 left 和 right 一开始都指向同一个中心位置(偶数长度回文则指向相邻两个字符)。只要 s[left] 和 s[right] 相等,就不断向两侧扩展,记录扩展出的回文串;每个中心都试过后,返回最长的回文子串。
双指针题目重要是:两个指针分别代表什么,什么时候移动左边,什么时候移动右边。
代码#
移动零#
1from typing import List2
3
4class Solution:5 def moveZeroes(self, nums: List[int]) -> None:6 n = len(nums)7 left = right = 08 while right < n:9 if nums[right]:10 nums[left], nums[right] = nums[right], nums[left]11 left += 112 right += 1盛最多水的容器#
1from typing import List2
3
4class Solution:5 def maxArea(self, height: List[int]) -> int:6 left = 07 right = len(height) - 18
9 ans = 010 while left < right:11 if height[right] < height[left]:12 h = height[right]13 area = (right - left) * h14 if area > ans:15 ans = area16 right -= 117 while left < right and height[right] < h:18 right -= 119 else:20 h = height[left]21 area = (right - left) * h22 if area > ans:23 ans = area24 left += 125 while left < right and height[left] < h:26 left += 127
28 return ans三数之和(双指针)#
1from typing import List2
3
4class Solution:5 def threeSum(self, nums: List[int]) -> List[List[int]]:6 nums.sort()7 ans = []8 n = len(nums)9
10 for i in range(n - 2):11 if i > 0 and nums[i] == nums[i - 1]:12 continue13 if nums[i] > 0:14 break15
16 left = i + 117 right = n - 118 while left < right:19 total = nums[i] + nums[left] + nums[right]20 if total < 0:21 left += 122 elif total > 0:23 right -= 124 else:25 ans.append([nums[i], nums[left], nums[right]])26 left += 127 right -= 128 while left < right and nums[left] == nums[left - 1]:29 left += 130 while left < right and nums[right] == nums[right + 1]:31 right -= 132
33 return ans接雨水#
1from typing import List2
3
4class Solution:5 def trap(self, height: List[int]) -> int:6 ans = 07 left = 08 right = len(height) - 19 left_max = 010 right_max = 011
12 while left < right:13 left_max = max(left_max, height[left])14 right_max = max(right_max, height[right])15
16 if height[left] < height[right]:17 ans += left_max - height[left]18 left += 119 else:20 ans += right_max - height[right]21 right -= 122
23 return ans最长回文子串(中心扩展)#
1class Solution:2 def longestPalindrome(self, s: str) -> str:3 def expand(left: int, right: int) -> str:4 while left >= 0 and right < len(s) and s[left] == s[right]:5 left -= 16 right += 17 return s[left + 1:right]8
9 ans = ""10 for i in range(len(s)):11 odd = expand(i, i)12 even = expand(i, i + 1)13 ans = max(ans, odd, even, key=len)14 return ans参考资料#
- 移动零
- 盛最多水的容器
- 三数之和
- 接雨水
- 最长回文子串
- LeetCode 移动零:https://leetcode.com/problems/move-zeroes/
- LeetCode 盛最多水的容器:https://leetcode.com/problems/container-with-most-water/
- LeetCode 三数之和:https://leetcode.com/problems/3sum/
- LeetCode 接雨水:https://leetcode.com/problems/trapping-rain-water/
- LeetCode 最长回文子串:https://leetcode.com/problems/longest-palindromic-substring/
- 力扣移动零题解:https://leetcode.cn/problems/move-zeroes/solutions/489622/yi-dong-ling-by-leetcode-solution/
- 力扣盛最多水的容器题解:https://leetcode.cn/problems/container-with-most-water/solutions/11491/container-with-most-water-shuang-zhi-zhen-fa-yi-do/
- 力扣三数之和题解:https://leetcode.cn/problems/3sum/solutions/284681/san-shu-zhi-he-by-leetcode-solution/
- 力扣接雨水题解:https://leetcode.cn/problems/trapping-rain-water/solutions/692342/jie-yu-shui-by-leetcode-solution-tuvc/
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分内容可能已过时
评论区
分享你的想法,与大家交流讨论
音乐
暂未播放



