数组双指针
双指针分为「对撞指针」、「快慢指针」、「分离双指针」。
- 对撞指针:两个指针方向相反。适合解决查找有序数组中满足某些约束条件的一组元素问题、字符串反转问题。
- 快慢指针:两个指针方向相同。适合解决数组中的移动、删除元素问题,或者链表中的判断是否有环、长度问题。
- 分离双指针:两个指针分别属于不同的数组 / 链表。适合解决有序数组合并,求交集、并集问题。
难度简单491
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s
的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:s = ["h","e","l","l","o"] 输出:["o","l","l","e","h"]
示例 2:
输入:s = ["H","a","n","n","a","h"] 输出:["h","a","n","n","a","H"]
解题思路:使用两个指针指向数组头和尾,如果指向的字符不相等就进行交换,当left=right或left>right时停止交换。
代码:
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left = 0
right = len(s)-1
if left==right: # 数组只有1个元素
return
while left<right:
if s[left]!=s[right]:
s[left],s[right]=s[right],s[left]
left += 1
right -= 1
难度简单2326
给你一个有序数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
解题思路:使用快慢指针求解,相同元素不复制。
代码:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if len(nums)<2:
return len(nums)
slow = 0
fast = 1
while fast<len(nums):
if nums[slow]!=nums[fast]:
slow += 1
nums[slow]=nums[fast]
fast += 1
return slow+1
难度中等602
给你一个有序数组 nums
,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。
解题思路:1. 按照和上一题一样的思路,只不过加入FLAG=1判断元素是否已经重复过一次,并且下一次如果快慢指针的元素不同,重置FLAG=0。2. 运行发现使用快慢指针,运行速度不如评论区中取巧的方法(遍历有序的数组,去掉长度范围2外的重复元素)。
代码1:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if len(nums)<=2:
return len(nums)
slow = 0
fast = 1
flag = 0
while fast<len(nums):
if nums[slow]!=nums[fast]:
flag = 0
slow += 1
nums[slow]=nums[fast]
fast += 1
elif flag==0:
flag = 1
slow += 1
nums[slow]=nums[fast]
fast += 1
elif flag==1:
fast += 1
return slow+1
代码2:
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
i = 0
for e in nums:
if i < 2 or e != nums[i - 2]:
nums[i] = e
i += 1
return i