"""
two-pointers, slide-window - EASY problems from leetcode for bytedance
141. 环形链表
"""
question_list = [141,167,26,88,392,350,27]
"""
141. 环形链表
167. 两数之和 II - 输入有序数组
88. 合并两个有序数组
26. 删除有序数组中的重复项
392. 判断子序列
350. 两个数组的交集 II
27. 移除元素(数组原地移除元素)
"""
def hasCycle(self, head):
"""
快慢指针追,只要快慢相等了就一定有环。
或者用hash也行,空间复杂度高一些。
"""
if not head:
return False
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
return True
return False
"""
167. 两数之和 II - 输入有序数组
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
"""
def twoSum_2(numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
i, j = 0, len(numbers) - 1
while i < j:
s = numbers[i] + numbers[j]
if s == target:
return [i + 1, j + 1]
elif s < target:
i += 1
else:
j -= 1
return []
"""
88. 合并两个有序数组
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
"""
def merge_two_seq_arrays(nums1, m, nums2, n):
"""
思路:双指针+逆向填充。只要双指针,时间复杂度就是O(m+n),逆向填充可保证空间复杂度是O(1)。
关键:逆向填充,merge时反着来
"""
i = m - 1
j = n - 1
z = m + n - 1
while i >= 0 and j >= 0:
if nums1[i] >= nums2[j]:
nums1[z] = nums1[i]
i -= 1
else:
nums1[z] = nums2[j]
j -= 1
z -= 1
if i < 0:
while j >= 0:
nums1[z] = nums2[j]
j -= 1
z -= 1
"""
26. 删除有序数组中的重复项
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
"""
def removeDuplicates(nums):
"""
快慢指针,原地替换
tips:其实也可以不用记录上一个值,从1开始遍历就行了。
"""
i, j = 0, 0
last = float('inf')
while i < len(nums):
if nums[i] != last:
nums[j] = nums[i]
j += 1
last = nums[i]
i += 1
return j
"""
392. 判断子序列
输入:s = "abc", t = "ahbgdc"
输出:true
"""
def isSubsequence(s, t):
"""
双指针
"""
i, j = 0, 0
while i < len(s) and j < len(t):
if s[i] == t[j]:
i += 1
j += 1
else:
j += 1
if i == len(s):
return True
return False
"""
350. 两个数组的交集 II
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
"""
def intersect(nums1, nums2):
"""
[快慢指针]
先排序!!
然后再双指针,各走各的
"""
nums1.sort()
nums2.sort()
ret = []
i, j = 0, 0
while i < len(nums1) and j < len(nums2):
if nums1[i] == nums2[j]:
ret.append(nums1[i])
i += 1
j += 1
elif nums1[i] > nums2[j]:
j += 1
else:
i += 1
return ret
"""
27. 移除元素
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,_,_]
解释:你的函数函数应该返回 k = 2, 并且 nums 中的前两个元素均为 2。
你在返回的 k 个元素之外留下了什么并不重要(因此它们并不计入评测)。
"""
def removeElement(nums, val):
"""
[快慢指针]
原地重新赋值,两个指针,一个遍历指针,一个赋值指针。这题其实有点意思。
"""
idx, ret = 0, 0
for num in nums:
if num != val:
nums[idx] = num
idx += 1
ret += 1
return ret
"""
283. 移动零
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
"""
def moveZeroes(nums):
"""
[快慢指针]
原地重新赋值,两个指针,一个遍历指针,一个赋值指针。跟【27.移除元素】一样的
"""
i, j = 0, 0
while i < len(nums):
if nums[i] != 0:
nums[j] = nums[i]
j += 1
i += 1
while j < len(nums):
nums[j] = 0
j += 1