好题
203 删除列表中val为k的值
技巧, 用dummy head
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy = ListNode(next = head)
cur = dummy
while cur.next:
if cur.next.val == val:
cur.next = cur.next.next
else:
cur = cur.next
return dummy.next
206 翻转列表
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
cur = head
pre = None
while (cur):
cur.next = pre
pre = cur
cur = cur.next
return pre
但是这个过不了, 原因his第一步更新了cur.next, 第三步用了cur.next
141 判断是否有环
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head or not head.next:
return False
l = head
r = head.next
while l != r:
if r == None or r.next == None:
return False
l = l.next
r = r.next.next
return True
如果该链表中有环,那么「兔子」会先于「乌龟」进入环,并且一直在环内移动。等到「乌龟」进入环时,由于「兔子」的速度快,它一定会在某个时刻与乌龟相遇,即套了「乌龟」若干圈。
19 删除倒数第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]:
if head == None or head.next == None:
return None
r = head
l = ListNode(next = head)
for _ in range(n):
r = r.next
while r:
r = r.next
l = l.next
l.next = l.next.next
return l
一开始写成的是这样, 但是最后[1, 2] n=2 过不了
原因是:
23 合并k个有序链表
ListNode.__lt__ = lambda a, b: a.val < b.val # 让堆可以比较节点大小
class Solution:
def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
cur = dummy = ListNode() # 哨兵节点,作为合并后链表头节点的前一个节点
h = []
for head in lists:
if head:
h.append(head)
heapify(h) # 堆化
while h: # 循环直到堆为空
node = heappop(h) # 剩余节点中的最小节点
if node.next: # 下一个节点不为空
heappush(h, node.next) # 下一个节点有可能是最小节点,入堆
cur.next = node # 合并到新链表中
cur = cur.next # 准备合并下一个节点
return dummy.next # 哨兵节点的下一个节点就是新链表的头节点
24 两两swap pairs
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head == None or head.next == None:
return head
remaining = self.swapPairs(head.next.next)
temp = head.next
head.next.next = head
head.next = remaining
return temp
148 排序链表
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表
class Solution:
def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head == None or head.next == None:
return head
l = head
r = head.next
while r and r.next:
l = l.next
r = r.next.next
mid = l.next
l.next = None
left, right = self.sortList(head), self.sortList(mid)
dummy = head = ListNode()
while left!= None and right != None:
if left.val < right.val:
head.next = left
left = left.next
head = head.next
else:
head.next = right
right = right.next
head = head.next
if left == None:
while right:
head.next = right
head = head.next
right = right.next
else:
while left:
head.next = left
head = head.next
left = left.next
return dummy.next
学习一下找中点的方法:
l = head, r = head.next,
l += 1, r += 2
147 对链表进行插入排序
class Solution:
def insertionSortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if head == None or head.next == None:
return head
remaining = self.insertionSortList(head.next)
dummy = l = ListNode(next = remaining)
r = remaining
while r != None and r.val < head.val:
r = r.next
l = l.next
l.next = head
head.next = r
return dummy.next
25 k个一组翻转
class Solution:
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
if head == None:
return head
temp = head
for _ in range(k-1):
temp = temp.next
if temp == None:
return head
temp = temp.next
remaining = self.reverseKGroup(temp, k)
dummy = ListNode(next = head)
prev = dummy
curr = head
for _ in range(k):
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node
dummy.next.next = remaining
return prev