27 移除元素
题目描述:
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
题解:双指针
快指针出去寻宝,找到需要的宝藏由慢指针存储
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
# 快慢指针
fast = 0 # 快指针
slow = 0 # 慢指针
size = len(nums)
while fast < size: # 不加等于是因为,a = size 时,nums[a] 会越界
# slow 用来收集不等于 val 的值,如果 fast 对应值不等于 val,则把它与 slow 替换
if nums[fast] != val:
nums[slow] = nums[fast]
slow += 1
fast += 1
return slow
26 移除有序数组中的重复项
题目描述:
给你一个 非严格递增排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
题解:双指针
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
l = len(nums)
if l <= 1:
return l
slow, fast = 0, 0
while fast < l:
if nums[fast] != nums[slow]:
#注意:slow先往后挪一个格子再赋值
slow += 1
nums[slow] = nums[fast]
fast += 1
#注意:slow + 1,因为要返回长度,而此时slow是下标
return slow + 1
283 移动零
题目描述:
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。
题解:双指针
区别在于找到需要的宝藏之后需要左右互换值,把不需要的宝藏往后挪
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
l = len(nums)
slow, fast = 0, 0
while fast < l:
if nums[fast] != 0:
nums[slow], nums[fast] = nums[fast], nums[slow]
#注意这里先交换,再将慢指针往后挪
slow += 1
fast += 1
844 比较含退格的字符串
题目描述:
给定 s
和 t
两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true
。#
代表退格字符。注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:s = "ab#c", t = "ad#c" 输出:true 解释:s 和 t 都会变成 "ac"。
示例 2:
输入:s = "ab##", t = "c#d#" 输出:true 解释:s 和 t 都会变成 ""。
示例 3:
输入:s = "a#c", t = "b" 输出:false 解释:s 会变成 "c",但 t 仍然是 "b"。
题解:双指针
class Solution:
def backspaceCompare(self, s: str, t: str) -> bool:
def real_text(st):
st = list(st)
l = len(st)
fast, slow = 0, 0
while fast < l:
if st[fast] != '#' :
st[slow] = st[fast]
slow += 1
elif st[fast] == '#' and slow > 0:
slow -= 1
fast += 1
return str(st[:slow])
return real_text(s) == real_text(t)
977 有序数组的平方
题目描述:
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
题解一:归并 + 双指针
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
l = len(nums)
i, neg = 0, -1
for i, num in enumerate(nums):
if num < 0:
neg = i
else:
break
ans = []
i , j = neg, neg + 1
while i >=0 or j < l:
if i < 0:
ans.append(nums[j] * nums[j])
j += 1
elif j >= l:
ans.append(nums[i] * nums[i])
i -= 1
elif nums[j] * nums[j] <= nums[i] * nums[i]:
ans.append(nums[j] * nums[j])
j += 1
else:
ans.append(nums[i] * nums[i])
i -= 1
return ans
题解二:双指针
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
l = len(nums)
#注意从后往前插入数组要先分配空间,不能用append
ans = [0] * l
i, j, pos = 0, l-1, l-1
while i <= j:
if nums[i] * nums[i] > nums[j] * nums[j]:
ans[pos] = nums[i] * nums[i]
i += 1
else:
ans[pos] = nums[j] * nums[j]
j -= 1
pos -= 1
return ans
88 合并两个有序数组:
题目描述:
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0
,应忽略。nums2
的长度为 n
。
题解:倒序双指针
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
i, j, pos = m-1, n-1, m+n-1
while j >= 0:
#nums1还有元素并且比当前nums2的大,放nums的元素
if i >= 0 and nums1[i] > nums2[j]:
nums1[pos] = nums1[i]
i -= 1
#否则入nums2的元素,直到nums2的元素放完
else:
nums1[pos] = nums2[j]
j -= 1
pos -= 1
class Solution:
def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
"""
Do not return anything, modify nums1 in-place instead.
"""
p1, p2, p = m-1, n-1, m+n-1
while p2 >=0:
if p1 < 0:
nums1[p] = nums2[p2]
p2 -= 1
elif nums1[p1] < nums2[p2]:
nums1[p] = nums2[p2]
p2 -= 1
else:
nums1[p] = nums1[p1]
p1 -= 1
p -= 1
19 删除链表的倒数第n个节点
题目描述:
给你一个链表,删除链表的倒数第 n
个结点,并且返回链表的头结点。
题解:双指针
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
slow = fast = head
# if not head.next:
# return head.next
for i in range(n):
fast = fast.next
# 删除的是头节点
if not fast:
return head.next
while fast.next:
slow = slow.next
fast = fast.next
slow.next = slow.next.next
return head