title: LinkedList系列
comments: true
date: 2017-07-10 23:46:55
updated: 2017-07-17 09:46:55
categories: Leetcode
tags: [LinkedList, TwoPointer]
LinkedList系列總結
24/27
[x] Easy
[x] Medium
[x] Hard
這種題,多畫圖,一步步來,確定哪個node指向哪個node就會好一點,之后把圖放上來,會更容易復習!
基礎
dummyNode
適用于頭節點需要進行操作,增刪改,亦或者保存頭節點,不被后續操作改變
dummy = ListNode(0)
dummy.next = head
curr = head
reverseList
Iterative版本,簡要來說就是記錄下一節點,當前節點指向上一節點,同步移動上一節點和當前節點。最后的curr為空,prev為頭也就是最初鏈表的最后一個元素
prev = None
curr = head
while curr:
nextNode = curr.next
curr.next = prev
prev = curr
curr = nextNode
return prev
Recursive版本的,一直到底,然后倒敘指針
second = head.next
head.next = None
rest = self.reverseList(second)
second.next = head
return rest
變種1 92. Reverse Linked List II
除了移動節點之外,關鍵是鏈接頭和尾
pre.next.next = curr //pre.next 為最初的頭,.next則鏈接后來的尾和最初的尾 1-2-3-4-5,1-4-3-2-5,2-5
pre.next = newHead // 1-4
快慢指針
用于檢測環和找中點,見于
- Linked List Cycle
- Linked List Cycle II
·234. Palindrome Linked List
fast, slow = head, head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
Medium版本
·369. Plus One Linked List
·445. Add Two Numbers II
本質上用stack保存節點信息,然后不斷在前方添加節點
node.val = add_value % 10
carry = ListNode(add_value / 10)
carry.next = node
node = carry
add_value /= 10
Merge,Move系列
·21. Merge Two Sorted Lists
·328. Odd Even Linked List
·86. Partition List
curr = dummy
while l1 and l2:
if l1.val < l2.val:
curr.next = l1
l1 = l1.next
else:
curr.next = l2
l2 = l2.next
curr = curr.next
保證兩個list都存在,然后剩余的append在后面;然后移動節點的過程中要數好步伐while even and even.next:
·160. Intersection of Two Linked Lists
·19. Remove Nth Node From End of List
`61. Rotate List
trick的地方是找到最后一個node,并且鏈接第一個,使用常用模版,不過稍加改動,因為要找到最后一個node而不是長度,所以要提前終止循環
length = 1
while curr.next:
curr = curr.next
length += 1
curr.next = head
move = length-1-k%length
綜合
`143. Reorder List
結合 以上多種方法,快慢指針找中點,反轉,merge
mid = self.findMiddle(head)
tail = self.reverse(mid.next)
mid.next = None
self.merge(head, tail)
`23. Merge k Sorted Lists
一種方法是利用merge two list然后不斷divide and conquer,另外一種比較簡潔的是利用PriorityQueue,然后不斷put和poll()進而每一個node都是所有優先隊列中最小的一個
q = PriorityQueue()
for node in lists:
if node: ## empty
q.put((node.val, node))
while q.qsize():
curr.next = q.get()[1]
curr = curr.next
if curr.next:
q.put((curr.next.val, curr.next))
`82. Remove Duplicates from Sorted List II
因為要移除所有重復的node,所以勢必要prev保存上一節點,然后如果中間因為重復節點而curr!= prev.next,要把prev節點的next放到curr的next節點,因為curr為重復節點的最后一個
while curr:
while curr.next and curr.val == curr.next.val: ## [1]
curr = curr.next
if prev.next != curr:
prev.next = curr.next
curr = prev.next
else:
prev = prev.next
curr = curr.next
`109. Convert Sorted List to Binary Search Tree
用helperfunction幫助,每一步找出子鏈表的中點,然后分別遞歸left和right節點。
while fast!= tail and fast.next != tail:
fast = fast.next.next
slow = slow.next
root = TreeNode(slow.val)
root.left = self.helper(head, slow)
root.right = self.helper(slow.next, tail)
·148. Sort List
分治法,然后分別對子鏈表merge
prev,fast, slow = None, head, head
while fast and fast.next:
prev = slow
slow = slow.next
fast = fast.next.next
prev.next = None ## cut the middle
l1 = self.sortList(head)
l2 = self.sortList(slow)
return self.merge(l1, l2)
·24. Swap Nodes in Pairs
這道題勤畫圖,一步步來就好,iterative的方法比較煩,不過是Reverse Nodes in k-Group
的簡化版,那道題是LinkedList集大成者
while curr.next and curr.next.next:
first = curr.next # 1
second = curr.next.next #2
first.next = second.next # 1-3
curr.next = second #-2
curr.next.next = first #2-1
curr = curr.next.next # 1
`25. Reverse Nodes in k-Group
這道題是一道典型的綜合題,適合復習備考多刷。它的子function是reverseList的改良,因為需要保存頭節點和尾節點,所以需要設置lastNode和nextNode,然后與之相對應的就是lastNode不斷和后面的節點進行調換。可以看看對比
/*
* 0->1->2->3->4->5->6
* | |
* pre next
*
* after calling pre = reverse(pre, next)
*
* 0->3->2->1->4->5->6
* | |
* pre next
*/
def reverseNode(self, pre, nextNode):
lastNode = pre.next
curr = lastNode.next
while curr != nextNode:
lastNode.next = curr.next
curr.next = pre.next
pre.next = curr
curr = lastNode.next
return lastNode
def reverseList(self, head):
if not head or not head.next:
return head
prev = None
curr = head
while curr:
nextNode = curr.next
curr.next = prev
prev = curr
curr = nextNode
return prev