赞
踩
双指针(Two Pointers):指的是在遍历元素的过程中,不是使用单个指针进行访问,而是使用两个指针进行访问,从而达到相应的目的。
双指针分为「对撞指针」、「快慢指针」、「分离双指针」。
对撞指针:两个指针方向相反。适合解决查找有序数组中满足某些约束条件的一组元素问题、字符串反转问题。
快慢指针:两个指针方向相同。适合解决数组中的移动、删除元素问题,或者链表中的判断是否有环、长度问题。
分离双指针:两个指针分别属于不同的数组 / 链表。适合解决有序数组合并,求交集、并集问题。
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组
[1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
class Solution: def maxArea(self, height: List[int]) -> int: result = 0 left = 0 right = len(height) - 1 while left < right: # 求解矩形的面积 l = right - left h = min(height[left], height[right]) area = l*h # 需要不断维持更新最大值 result = max(result, area) # 应该使得 较低直线的高度尽可能的高 # 当left指向的直线高度较低,向右移动 if height[left] < height[right]: left += 1 # 当right指向的直线高度较低,向左移动 else: right -= 1 return result
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left = 0
right = len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
return s
输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
# 定义两个指针
slow = 0
fast = 1
# 可以视作把非重复元素放在数组左边
while fast < len(nums):
if nums[slow] != nums[fast]:
slow += 1
nums[slow] = nums[fast]
fast += 1
return slow + 1
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
class Solution: def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]: # 分离双指针一般用于处理有序数组合并,求交集、并集问题 # 1 先将两个数组排序 nums1.sort() nums2.sort() # 使用双指针求交集 point1 = 0 point2 = 0 result = [] while point1 < len(nums1) and point2 < len(nums2): # 元素同时出现在两个数组 if nums1[point1] == nums2[point2]: # 保证数组没有重复元素 if nums1[point1] not in result: result.append(nums1[point1]) # 齐头并进 point1 += 1 point2 += 1 # point1落后于point2,需要追赶 elif nums1[point1] < nums2[point2]: point1 += 1 # point2落后于point1,需要追赶 else: point2 += 1 return result
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
# 定义两个指针,分别指向数组的尾部
p1 = m-1
p2 = n-1
p = m + n - 1
while p1 >= 0 and p2 >= 0:
if nums1[p1] <= nums2[p2]:
nums1[p] = nums2[p2]
p2 -= 1
else:
nums1[p] = nums1[p1]
p1 -= 1
p -= 1
# 最后把nums2中的剩余元素赋值到nums1中
nums1[:p2+1] = nums2[:p2+1]
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
slow = 2
fast = 2
# 因为有序,所以当 nums[slow-2] = nums[slow]时,
# 必有nums[slow] = nums[slow-1] = nums[slow-2]
# 不相等时进行添加
while fast < len(nums):
if nums[slow-2] != nums[fast]:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: result = [] # 结果输出 n = len(nums) # 先将数组递增排列 nums.sort() # 定义双指针 a, left, right for i in range(n): if i > 0 and nums[i] == nums[i-1]: continue left = i+1 right = n-1 # 双指针寻找区间 while left < right: # 答案中不可以包含重复的三元组,对于重复的元素直接跳过 while left < right and left > i+1 and nums[left] == nums[left-1]: left += 1 while left < right and right < n-1 and nums[right] == nums[right+1]: right -= 1 # 满足条件的三元组 if left < right and nums[i] + nums[left] + nums[right] == 0: result.append([nums[i], nums[left], nums[right]]) left += 1 right -= 1 elif nums[i] + nums[left] + nums[right] > 0: right -= 1 else: left += 1 return result
以上问题都来源于力扣:
力扣>
参考来源:https://algo.itcharge.cn/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。