leetcode(12)連結串列系列題目
阿新 • • 發佈:2022-05-16
21. 合併兩個有序連結串列
class Solution: def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]: if not list1: return list2 if not list2: return list1 if list1.val < list2.val: list1.next = self.mergeTwoLists(list1.next, list2) return list1 else: list2.next = self.mergeTwoLists(list1, list2.next) return list2
23. 合併K個升序連結串列
思路 1:
歸併,分而治之
連結串列兩兩合併
class Solution: def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: if not lists: return n = len(lists) return self.merge(lists, 0, n - 1) def merge(self, lists, left, right): if left == right: return lists[left] mid = (left + right) // 2 l = self.merge(lists, left, mid) r = self.merge(lists, mid + 1, right) return self.mergeTwo(l, r) def mergeTwo(self, l1, l2): if not l1: return l2 if not l2: return l1 if l1.val < l2.val: l1.next = self.mergeTwo(l1.next, l2) return l1 else: l2.next = self.mergeTwo(l1, l2.next) return l2
思路 2:
呼叫優先順序佇列,實現最小堆
時間複雜度:O(n∗log(k)),n 是所有連結串列中元素的總和,k 是連結串列個數。
class Solution: def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]: import heapq #呼叫堆 minHeap = [] for l in lists: while l: heapq.heappush(minHeap, l.val) #把l中的資料逐個加到堆中 l = l.next dummy = ListNode(0) p = dummy #構造虛節點 while minHeap: val = heapq.heappop(minHeap) #依次彈出最小堆的資料 p.next = ListNode(val) p = p.next return dummy.next
206.反轉連結串列
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre, cur = None, head
while cur:
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
return pre
25. K 個一組翻轉連結串列
class Solution:
def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
cur = head
for _ in range(k):
if not cur:
return head # 如果head後續節點數不足k個直接返回head
cur = cur.next
pre, cur = None, head
for _ in range(k): # 將包括head往後的k個節點翻轉
tmp = cur.next
cur.next = pre
pre = cur
cur = tmp
head.next = self.reverseKGroup(cur, k) # 遞迴得到下一段k個節點的反轉後的頭結點
# head已經是當前段k個節點的尾節點了,指向下一段的反轉後的頭結點
return pre
24. 兩兩交換連結串列中的節點
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
res = ListNode(next = head)
pre = res
while pre.next and pre.next.next:
cur = pre.next
tmp = pre.next.next
cur.next = tmp.next
tmp.next = cur
pre.next = tmp
pre = pre.next.next
return res.next
92. 反轉連結串列 II
class Solution:
def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
# 設定 dummyNode 是這一類問題的一般做法
# dummy = ListNode(-1)
# dummy.next = head
dummy = ListNode(next = head) # 等價於
pre = dummy
for _ in range(left - 1):
pre = pre.next
cur = pre.next
for _ in range(right - left):
next = cur.next
cur.next = next.next
next.next = pre.next
pre.next = next
return dummy.next
143.重排連結串列
203. 移除連結串列元素
劍指 Offer 18. 刪除連結串列的節點
劍指 Offer 22. 連結串列中倒數第k個節點
19. 刪除連結串列的倒數第 N 個結點
劍指 Offer 06. 從尾到頭列印連結串列
劍指 Offer 35. 複雜連結串列的複製
141. 環形連結串列
142. 環形連結串列 II
160. 相交連結串列
參考資料:
從遞迴到迭代:由淺入深……