前言
- 阴天睡得还挺舒服,9点半才醒,用刷题开启美好新一天!
哈希表
```python
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
seen = set() # 哈希集合
# seen = {} # 哈希字典
cur = head
while cur:
if cur in seen: # 有重复的节点则有环
return True
seen.add(cur) # 直接存节点
# seen[cur] = True # 将节点作为键,值设为True
cur = cur.next
return False
```
快慢指针
```python
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
slow = fast = head # 乌龟和兔子同时从起点出发
while fast and fast.next:
slow = slow.next # 乌龟走一步
fast = fast.next.next # 兔子走两步
if fast == slow: # 兔子追上乌龟(套圈),说明有环
return True
return False # 访问到了链表末尾,无环
```
快慢指针
```python
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:
fast = slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if slow == fast: # 快慢指针相遇,s走了nb,f走了2nb
fast = head # 入口处需要a+nb,s已经走了nb
while fast != slow: # 同时走a就可到达入口
fast = fast.next
slow = slow.next
return fast
return None
```
迭代法
```python
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
prehead = ListNode(-1)
precur = prehead
while list1 and list2:
if list1.val <= list2.val: # 把较小值接到precur后面
precur.next = list1
list1 = list1.next
else:
precur.next = list2
list2 = list2.next
precur = precur.next # 记得让precur前进
# 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
precur.next = list1 if list1 else list2
return prehead.next
```
递归法
```python
class Solution:
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
if list1 is None:
return list2
if list2 is None:
return list1
if list1.val < list2.val:
list1.next = self.mergeTwoLists(list1.next, list2)
return list1
else:
list2.next = self.mergeTwoLists(list2.next, list1)
return list2
```
模拟------转数字
```python
class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
# 链表转化为数字
def getNum(head):
num = 0
flag = 1
while head != None:
num += head.val * flag
head = head.next
flag *= 10
return num
# 计算和
twoSum = getNum(l1) + getNum(l2)
# 和为0直接返回0节点
if twoSum == 0:
return ListNode(0)
# 循环生成新链表
head = cur = ListNode(-1)
while twoSum != 0:
cur.next = ListNode(twoSum % 10)
cur = cur.next
twoSum //= 10 # 整除
return head.next
```
模拟------进位
```python
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
# 创建一个结点值为 None 的头结点, dummy 和 p 指向头结点, dummy 用来最后返回, p 用来遍历
dummy = p = ListNode(None)
s = 0 # 初始化进位 s 为 0
while l1 or l2 or s:
# 如果 l1 或 l2 存在, 则取l1的值 + l2的值 + s(s初始为0, 如果下面有进位1, 下次加上)
s += (l1.val if l1 else 0) + (l2.val if l2 else 0)
p.next = ListNode(s % 10) # p.next 指向新链表, 用来创建一个新的链表
p = p.next # p 向后遍历
s //= 10 # 有进位情况则取模, eg. s = 18, 18 // 10 = 1
l1 = l1.next if l1 else None # 如果l1存在, 则向后遍历, 否则为 None
l2 = l2.next if l2 else None # 如果l2存在, 则向后遍历, 否则为 None
return dummy.next # 返回 dummy 的下一个节点, 因为 dummy 指向的是空的头结点, 下一个节点才是新建链表的后序节点
```
递归------进位
```python
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
def dfs(l, r, i):
# 终止条件:都为空节点且进位为0
if not l and not r and not i: return None
s = (l.val if l else 0) + (r.val if r else 0) + i
node = ListNode(s % 10) # 当前节点
node.next = dfs(l.next if l else None, r.next if r else None, s // 10) # 接上递归链表
return node
return dfs(l1, l2, 0)
```
双指针
```python
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy = ListNode(0, head) # 直接创建虚拟头节点
fast = slow = dummy # 双指针
# 快指针先走
while n != 0:
fast = fast.next
n -= 1
# 双指针一起走直到fast到底
while fast.next != None:
fast = fast.next
slow = slow.next
# 删除节点
slow.next = slow.next.next
return dummy.next
```
模拟
```python
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
dummy = ListNode(0, head)
cur = dummy
while cur.next and cur.next.next:
pre = cur
cur = cur.next
temp = cur.next.next
pre.next = cur.next # 步骤1
pre.next.next = cur # 步骤2
cur.next = temp # 步骤3
return dummy.next
```
递归
```python
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 终止条件:如果剩0/1个节点,无法交换,直接返回
if not head or not head.next:
return head
# 交换头两个结点
newhead = head.next
head.next = self.swapPairs(newhead.next) # 接上后面交换好的结果
newhead.next = head
return newhead
```
后言
- 明天估计是不开组会的,今天猛猛刷了6道题!知识能进脑子的感觉真爽啊!