LeetCode | 双指针

981 字
5 分钟
LeetCode | 双指针

分类:双指针 / 总结

讲解#

双指针题目的核心是:用两个指针描述当前正在处理的位置或范围,然后根据规则移动指针。

移动零leftright 一开始都在数组最左侧。right 不断向右扫描数组;当 right 看到非零数时,就把它交换到 left 指向的位置,然后 left 向右移动。最后数组前面是所有非零数,后面是所有 0

盛最多水的容器left 一开始在最左侧,right 一开始在最右侧。两个指针夹住一个容器,计算当前面积后,移动较短的那一边;如果右边更短就移动 right,如果左边更短就移动 left。最后返回最大面积。

三数之和 先排序并固定第一个数 nums[i],然后让 lefti + 1 开始,right 从数组最右侧开始,在右侧区间里找另外两个数。如果三数之和偏小,就移动 left;如果三数之和偏大,就移动 right;如果等于 0,就记录答案并同时移动两个指针。最后返回所有不重复的三元组。

接雨水left 一开始在最左侧,right 一开始在最右侧,同时维护 left_maxright_max。如果左边高度更低,就结算 left 位置能接的水,然后移动 left;否则结算 right 位置能接的水,然后移动 right。最后返回总水量。

最长回文子串leftright 一开始都指向同一个中心位置(偶数长度回文则指向相邻两个字符)。只要 s[left]s[right] 相等,就不断向两侧扩展,记录扩展出的回文串;每个中心都试过后,返回最长的回文子串。

双指针题目重要是:两个指针分别代表什么,什么时候移动左边,什么时候移动右边。

代码#

移动零#

from typing import List
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
n = len(nums)
left = right = 0
while right < n:
if nums[right]:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right += 1

盛最多水的容器#

from typing import List
class Solution:
def maxArea(self, height: List[int]) -> int:
left = 0
right = len(height) - 1
ans = 0
while left < right:
if height[right] < height[left]:
h = height[right]
area = (right - left) * h
if area > ans:
ans = area
right -= 1
while left < right and height[right] < h:
right -= 1
else:
h = height[left]
area = (right - left) * h
if area > ans:
ans = area
left += 1
while left < right and height[left] < h:
left += 1
return ans

三数之和(双指针)#

from typing import List
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
ans = []
n = len(nums)
for i in range(n - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
if nums[i] > 0:
break
left = i + 1
right = n - 1
while left < right:
total = nums[i] + nums[left] + nums[right]
if total < 0:
left += 1
elif total > 0:
right -= 1
else:
ans.append([nums[i], nums[left], nums[right]])
left += 1
right -= 1
while left < right and nums[left] == nums[left - 1]:
left += 1
while left < right and nums[right] == nums[right + 1]:
right -= 1
return ans

接雨水#

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

最长回文子串(中心扩展)#

class Solution:
def longestPalindrome(self, s: str) -> str:
def expand(left: int, right: int) -> str:
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return s[left + 1:right]
ans = ""
for i in range(len(s)):
odd = expand(i, i)
even = expand(i, i + 1)
ans = max(ans, odd, even, key=len)
return ans

参考资料#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

LeetCode | 双指针
https://leetcode.cn/tag/two-pointers/problemset/
作者
平昊阳
发布于
2026-08-03
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
平昊阳
乘长风,破巨浪, 展鸿图于未央!
--
总访问量
--
访客数
公告
欢迎来到我的个人博客!欢迎关注交流吖!
更多相关公告,见
社交-留言」。
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
站点统计
文章
66
分类
16
标签
93
总字数
477,284
运行时长
0
最后活动
0 天前

文章目录