LeetCode-Python-86. 分隔連結串列(連結串列)
阿新 • • 發佈:2021-01-06
技術標籤:LeetCode 題解集合 700題連結串列演算法leetcode
給你一個連結串列和一個特定值 x ,請你對連結串列進行分隔,使得所有小於 x 的節點都出現在大於或等於 x 的節點之前。
你應當保留兩個分割槽中每個節點的初始相對位置。
示例:
輸入:head = 1->4->3->2->5->2, x = 3
輸出:1->2->2->4->3->5
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/partition-list
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
第一種思路:
暴力解,線性掃描輸入連結串列,然後維護兩個新的連結串列,第一個連結串列按順序儲存所有小於x 的節點,第二個連結串列按順序儲存所有大於或等於x的節點。
維護完成後,把第二個連結串列的頭接到第一個連結串列的尾部即可。
時間複雜度:O(N)
空間複雜度:O(N)
class Solution(object): def partition(self, head, x): """ :type head: ListNode :type x: int :rtype: ListNode """ smaller_dummy_head = ListNode(-2) larger_dummy_head = ListNode(-1) p = head ps, pl = smaller_dummy_head, larger_dummy_head while p: if p.val < x: ps.next = ListNode(p.val) ps = ps.next else: pl.next = ListNode(p.val) pl = pl.next p = p.next ps.next = larger_dummy_head.next return smaller_dummy_head.next
第二種思路:
原地演算法,
首先找到第一個大於等於x的Node,以它和它的preNode之間的間隔作為分割點,將連結串列一分為二,前一半叫做first_tail, 後一半叫做second_head。
為啥要這麼分呢,因為前一半連結串列已經排好序了,我們接下來要做的就是把後一半連結串列裡的所有比 x 小的Node 拿出來,再按順序插入到前一半連結串列的尾部。
時間複雜度:O(N)
空間複雜度:O(1)
class Solution(object): def partition(self, head, x): """ :type head: ListNode :type x: int :rtype: ListNode """ if not head: return head dummy_head = ListNode(-1, head) p = dummy_head second_head = None while p and p.next: if p.next.val >= x: first_tail = p second_head = p.next break p = p.next if not second_head: return head pre = second_head p = second_head.next while p: nxt = p.next if p.val < x: # pull out Node p, and append it to the first tail pre.next = p.next first_tail.next = p first_tail = first_tail.next p.next = second_head else: pre = p p = nxt return dummy_head.next def printLL(self, l): res = [] p = l while p: res.append(p.val) p = p.next print(res)