双指针(Two Pointers):在遍历元素的过程中,不是使用单个指针进行访问,而是使用两个指针进行访问,从而达到相应的目的. 如果两个指针方向相反,为对撞指针, 如果指针方向相同,称为快慢指针.如果两个指针分别属于不同的数组/链表,称为分离双指针
时间复杂度从O(n**2)降到了O(n)
left = 0
right = len(nums) - 1
while left < right:
if 满足要求的特殊条件:
return 符合条件的值
elif 一定条件1:
left += 1
elif 一定条件2:
right -= 1
return 没找到
slow = 0
fast = 1
while 没有遍历完:
if 满足一些条件:
slow += 1
fast += 1
return ans
left_1 = 0
left_2 = 0
while left_1 < len(nums1) and left_2 < len(nums2):
if 一定条件 1:
left_1 += 1
left_2 += 2
elif 一定条件 2:
left_1 += 1
elif 一定条件 3:
left_2 += 1
left = 0
right = 0
while right < len(nums):
window.append(nums[right])
if right - left + 1 >= window_size:
window.popleft()
left += 1
right += 1
left = 0
right = 0
while right < len(nums):
windows.append(nums[right])
while 窗口需要缩小:
window.popleft()
left += 1
right += 1
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
left = 0
right = len(numbers) - 1
while left < right:
if numbers[left] + numbers[right] == target:
return [left + 1, right + 1]
elif numbers[left] + numbers[right] > target:
right -= 1
else:
left += 1
class Solution:
def isPalindrome(self, s: str) -> bool:
s = s.lower()
left = 0
right = len(s) - 1
res_ls = list(range(48, 58)) + list(range(97, 123))
while left < right:
if ord(s[left]) in res_ls and ord(s[right]) in res_ls and s[left] == s[right]:
left += 1
right -= 1
elif ord(s[left]) not in res_ls:
left += 1
elif ord(s[right]) not in res_ls:
right -= 1
else:
return False
return True
class Solution:
def reverseString(self, s: List[str]) -> None:
left = 0
right = len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# 对数组进行排序
nums.sort()
n = len(nums)
ans = []
for first in range(n):
# 判断第一个指针选择的数字是否相同
if first >= 1 and nums[first] == nums[first - 1]:
continue
# 第三个指针从最后一个开始
third = n - 1
target = -nums[first]
for second in range(first + 1, n):
# 判断第二个指针是否相同
if second > first + 1 and nums[second] == nums[second - 1]:
continue
# 对撞指针的判断以及指针移动的判断
while second < third and nums[second] + nums[third] > target:
third -= 1
if second == third:
break
if nums[second] + nums[third] == target:
ans.append([nums[first], nums[second], nums[third]])
return ans
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
slow = 0
fast = 0
n = len(nums)
while fast < n:
if slow < 2 or nums[fast] != nums[slow - 2]:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
slow = 0
fast = 0
n = len(nums)
while fast < n:
if nums[fast] != 0:
nums[slow], nums[fast] = nums[fast], nums[slow]
slow += 1
fast += 1
return nums
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
left_1 = m - 1
right_1 = len(nums1) - 1
right_2 = n - 1
while left_1 >= 0 or right_2 >= 0:
if left_1 == -1:
nums1[right_1] = nums2[right_2]
right_2 -= 1
elif right_2 == -1:
nums1[right_1] = nums1[left_1]
left_1 -= 1
elif nums2[right_2] >= nums1[left_1]:
nums1[right_1] = nums2[right_2]
right_2 -= 1
else:
nums1[right_1] = nums1[left_1]
left_1 -= 1
right_1 -= 1
return nums1