# [資演] Linked list 練習 ###### tags: `資演` * [刪除 linked list 最中間的節點](https://leetcode.com/problems/delete-the-middle-node-of-a-linked-list/) 給定一個 linked list 的 `head`,把這個 list 的最中間那個節點刪除掉,並回傳那個新的 list 的 `head`。 ![](https://hackmd.io/_uploads/SyKLcG9AK.png) ![](https://hackmd.io/_uploads/By-_cGc0F.png) ![](https://hackmd.io/_uploads/r1ju9M5RF.png) :::spoiler 解答 這題只要使用兩個指針的技巧就可以輕鬆解決。 ``` # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution(object): def deleteMiddle(self, head): """ :type head: Optional[ListNode] :rtype: Optional[ListNode] """ if head.next is None: return None slow = head fast = head.next.next while (fast != None and fast.next != None): fast = fast.next.next slow = slow.next # tmp = slow.next slow.next = slow.next.next # del tmp return head ``` ::: * [旋轉 linked list](https://leetcode.com/problems/rotate-list/) 給定一個 linked list 的`head`以及一個整數`k`,把這個 list 向後旋轉`k`格。 ![](https://hackmd.io/_uploads/rJkLQX5CF.png) ![](https://hackmd.io/_uploads/B1t8X750F.png) :::spoiler 解答 這種牽涉到旋轉的問題,我們可以先遍歷一次list(順便算list的長度),把`tail`連接到`head`,也就是說,把原始的linked list變成一個circular linked list。 ``` class Solution(object): def rotateRight(self, head, k): if not head or not head.next: return head curr = head len = 1 while curr.next: curr = curr.next len += 1 curr.next = head k = k % len for i in range(len - k): curr = curr.next head = curr.next curr.next = None return head ``` ::: * [把 linked list 加 1](https://leetcode.com/problems/plus-one-linked-list/) 給定一個表示非負整數的 linked list 的`head`,回傳表示該整數加上1的 linked list 的`head`。 ![](https://hackmd.io/_uploads/Hyga9mcCK.png) :::spoiler 解答 這題和之前做過的[將兩個linked list相加](https://leetcode.com/problems/add-two-numbers/)類似,但是這題的linked list並沒有將數字反序儲存。因此,一個直覺的方法就是另外建立一個把原本的 list 反過來的 list,並進行簡單加法。然而,這麼做會消耗大量記憶體,在這邊我們可以使用不需要建立新 list 的方法。相對地,我們多次遍歷list,以時間換取空間。 ``` # Definition for singly-linked list. # class ListNode(object): # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution(object): def plusOne(self, head): """ :type head: ListNode :rtype: ListNode """ start = None node = head while node: if node.val < 9: start = node node = node.next if start: start.val += 1 node = start.next else: new = ListNode(1) new.next = head node = head head = new while node: node.val = 0 node = node.next return head ``` ::: * [相加兩個用 linked list 表示的多項式](https://leetcode.com/problems/add-two-polynomials-represented-as-linked-lists/) 多項式linked list是一種用來表示多項式的特殊 linked list 資料結構,其中每一個節點用來表示多項式的一個項。 每個節點有三個屬性: * `coefficient`: 一個整數,表示該項的係數。例如,$9x^4$ 的`coefficient`就是 9。 * `power`: 一個整數,表示該項的次方數。例如,$9x^4$ 的`power`就是 4。 * `next`: 用來連結到下一項的參數。 舉例來說,$5x^3 + 4x - 7$ 用linked list的表示方式如下圖: ![](https://hackmd.io/_uploads/Hks2-V50F.png) 注意在這邊我們的多項式必須按照次方降冪排列,並且忽略掉係數為0的項。 現在,給定兩個多項式linked list的`head`:`poly1`和`poly2`,我們要回傳一個多項式的`head`,用來表示給定的兩個多項式相加的多項式。如果結果是0,回傳`None`。 ![](https://hackmd.io/_uploads/HJ6dGNq0t.png) ![](https://hackmd.io/_uploads/ryLFfE9AY.png) :::spoiler 解答 這題事實上和merge兩個排列好的linked list類似。 ``` class Solution: def addPoly(self, poly1: 'PolyNode', poly2: 'PolyNode') -> 'PolyNode': head = node = PolyNode() while poly1 and poly2: if poly1.power > poly2.power: node.next = node = poly1 poly1 = poly1.next elif poly1.power < poly2.power: node.next = node = poly2 poly2 = poly2.next else: if coef := poly1.coefficient+poly2.coefficient: node.next = node = PolyNode(coef, poly1.power) poly1, poly2 = poly1.next, poly2.next node.next = poly1 or poly2 return head.next ``` :::