167. 两数之和 II - 输入有序数组
双指针
思路:由于答案肯定只有一个,只需要头尾开始遍历就好了,而遍历的条件:1.如果当前的和太大,那一定是右边的错,右边得减小;2.如果太小,则左边的错,左边得移动到更大的位置。
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
left = 0
right = len(numbers)-1
while numbers[left] + numbers[right] != target:
if numbers[left] + numbers[right] > target:
right -= 1
elif numbers[left] + numbers[right] < target:
left += 1
return left+1, right+1
88. 合并两个有序数组
归并,但是先是有序的两个数组。
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.
"""
pos = m + n - 1
m -= 1
n -= 1
while m >= 0 and n >= 0:
if nums1[m] > nums2[n]: # 选择大的进行复制到末尾
nums1[pos] = nums1[m]
m -= 1
else:
nums1[pos] = nums2[n]
n -= 1
pos -= 1
while n >= 0: # 如果第二组还剩就继续复制
nums1[pos] = nums2[n]
pos -= 1
n -= 1
return nums1
142. 环形链表 II
快慢数组+找到开始循环的节点
思路:找到开始循环的节点的位置比较难想得到:设定f s
是快慢指针走的步数:
则
有
f
=
2
s
又
∵
快
比
慢
走
多
n
圈
(
当
且
仅
当
头
尾
相
连
的
时
候
才
走
多
1
圈
)
∴
f
=
s
+
n
c
(
c
f
o
r
c
i
r
c
l
e
s
)
∴
s
=
n
c
这
就
意
味
着
从
开
始
到
相
遇
的
路
程
已
经
能
够
跑
整
数
个
c
了
,
但
是
这
个
距
离
有
一
部
分
是
非
循
环
的
部
分
a
∴
可
以
推
出
s
l
o
w
距
离
节
点
连
接
处
还
差
a
的
距
离
则有\\f = 2s \\又\because 快比慢走多n圈(当且仅当头尾相连的时候才走多1圈)\\ \therefore f = s+nc(c\ for \ circles)\\\therefore s = nc\\这就意味着从开始到相遇的路程已经能够跑整数个c了,但是这个距离有一部分是非循环的部分a\\\therefore可以推出slow距离节点连接处还差a的距离
则有f=2s又∵快比慢走多n圈(当且仅当头尾相连的时候才走多1圈)∴f=s+nc(c for circles)∴s=nc这就意味着从开始到相遇的路程已经能够跑整数个c了,但是这个距离有一部分是非循环的部分a∴可以推出slow距离节点连接处还差a的距离
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
if head == None:
return None
pos = 0
fast = head
slow = head
flag = 0
while fast != None and fast.next != None: # 先相遇
fast = fast.next.next
slow = slow.next
if fast == slow:
flag = 1
break
if flag == 0:
return None
fast = head # 后重新调整
while fast != slow: # 再次相遇即为连接处
fast = fast.next
slow = slow.next
return fast