【LeetCode】Linked List 實戰題目 206 24 141 142 25

P.S:

  • 鏈表的末尾的那個的 next 指向 None
  • 鏈表類的題目比較簡單,但是如果一不小心容易寫的特別複雜,需要在面試之前把複雜的鏈表題目再熟悉一下
    206 反轉鏈表(字節跳動、亞馬遜在半年內面試常考)
    本題參考題解
    在這裏插入圖片描述```

迭代法

def reverseList(head):
# 申請兩個節點 pre 和 cur ,pre 指向 None
pre, cur = None, head
while cur:
cur.next = pre # 然後將當前的節點指向 pre
pre = cur
cur = cur.next
return pre


迭代法簡略寫法

def reverseList(self, head: ListNode) -> ListNode:
    prev, cur = None, head 
    while cur:
        cur.next, prev, cur = prev, cur,cur.next 
    return prev

# 遞歸解法
def reverseList(head):
    # 遞歸終止條件是當前爲空,或者下一個節點爲空
    if not head or not head.next:return head
    # 這裏的 cur 就是最後一個節點
    cur = self.reverseList(head.next)
    head.next.next = head
    # 防止鏈表循環,需要將 head.next 設置爲 空
    head.next =None 
    return cur

對於 head.next.next = head的理解
參考動畫
在這裏插入圖片描述

# 騷氣遞歸寫法
    def reverseList(self,head):
        if not head or not head.next: return head
        curr, head.next.next, head.next = self.reverseList(head.next), head, None
        return curr

24 兩兩交換鏈表中的節點(阿里巴巴、字節跳動在半年內面試常考)

  # 法1:遞歸的方法
    def swapPairs(self, head: ListNode) -> ListNode:
      
        if not head or not head.next:return head
        new_start = head.next.next 
        head, head.next = head.next, head 
        head.next.next = self.swapPairs(new_start)
        return head 

採用增加虛擬節點的辦法:
時間複雜度是 O(N),空間複雜度是 O(1)
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        # 法二: DumyNode
        if not head or not head.next:return head
        dumy = ListNode(0)
        dumy.next = head
        cur = dumy 

        while cur.next and cur.next.next:
            first, sec = cur.next, cur.next.next
            cur.next = sec
            first.next = sec.next
            sec.next = first 
            cur = cur.next.next
        return dumy.next 

關於 cur = dumy 的幾點理解:
這裏的意思是 用 cur 指向當前的虛擬節點
在這裏插入圖片描述
141 環形鏈表(阿里巴巴、字節跳動、騰訊在半年內面試常考)
P.S: 環形鏈表比較套路的一個解法就是快慢指針

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        try:
            slow, fast = head, head.next 
            while slow is not fast:
                slow, fast = slow.next, fast.next.next 
            return True
        except:
            return False

142 環形鏈表 II

# 哈希的辦法 時間複雜度是O(N),空間複雜度是 O(N)
def detectCycle(head):
    visited = set()
    node = head
    
    while not node:
        if node in visited:return node
        else:
            visited.add(node)
            node = node.next
    return None
  • Floyd 算法 (時間複雜度是 O(N),空間複雜度是 O(1))
    • 第一步:判斷是否有環(一個跑的快的人和一個跑的慢的人,如果有環的話,肯定可以相遇)
    • 第二步:如果有環的話,我們初始化兩個指針,一個指向鏈表的頭部,一個指向相遇點,然後每次向前移動一步,知道他們相遇,相遇點就是 環的入口
class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
    # 第一步:判斷有沒有環
        try:
            slow, fast = head,head.next
            while fast is not slow:
                slow, fast = slow.next, fast.next.next 
        except:
            return None
        # 第二步:判斷環的入口在哪裏
        # 因爲 fast 是從 head.next 開始的,所以 fast 和 slow 相遇點應該是 slow.next
        slow = slow.next
        while head is not slow:
            head, slow = head.next, slow.next
        return head

25 K 個一組翻轉鏈表(字節跳動、猿輔導在半年內面試常考)

class Solution:
    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        dummy = jump = ListNode(0)
        dummy.next = l = r = head

        while True:
            count = 0
            # 把鏈表切分爲長度爲 k 的段
            while r and count < k:
                r = r.next
                count += 1
            #  在一個 長度爲 k 的子鏈表裏面進行交換
            if count == k:
                pre, cur = r, l   # 設置 pre = r, cur = l
                for _ in range(k):
                    cur.next, pre, cur = pre, cur,cur.next 
                jump.next, jump, l = pre, l, r   # 把各個子鏈表粘起來
            else:
                return dummy.next 

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章