LeetCode 86 | 鏈表基礎,一次遍歷處理鏈表中所有符合條件的元素


本文始發於個人公眾號:TechFlow,原創不易,求個關注


今天是LeetCode專題第53篇文章,我們一起來看LeetCode第86題,Partition List(鏈表歸並)。

本題的官方難度是Medium,點贊1276,反對296,通過率大約41%。總體來說,這題質量一般,通過率有點高,整體難度偏簡單,算是一道鏈表的基礎題。對鏈表熟悉一些的同學來說,問題不大。

題意

我們首先來看下題意,題意是說給定一個鏈表以及一個整數x,要求根據x來對鏈表中的元素進行歸並,使得鏈表的前半部分的結果小於x,后半部分的結果大於等於x。其他元素之間的相對順序保持不變。

我們來看樣例:

Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5 

根據3,我們可以將鏈表當中的元素分成小於3的與大於3的,其中小於3的元素有122,大於等於3的元素有435。我們返回的結果是122和435組成的新鏈表,並且122和435當中元素的互相順序沒有發生變化。

題解

由於問題當中並沒有對我們如何處理鏈表以及當中的元素做出限制,所以我們可以隨意操作這個鏈表以及其中的數據,很容易想到最簡單的方法就是我們根據x將鏈表當中的元素分成兩個部分,分別存入兩個鏈表當中,最后再將這兩個鏈表合並在一起。合並的方式也非常簡單,只需要將鏈表連接在一起即可。

這種思路非常無腦,幾乎不涉及什么難點,只需要遍歷鏈表然后分別插入不同的鏈表即可,最后再把這兩個鏈表合並成一個就搞定了。

我們很容易就可以寫出代碼:

# Definition for singly-linked list.
# class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution:  def partition(self, head: ListNode, x: int) -> ListNode:  # 創建兩個鏈表  left = ListNode(0)  right = ListNode(0)  # 以及用來遍歷這兩個鏈表的指針  ln = left  rn = right  pnt = head  while pnt is not None:  # 小於x則插入left,否則插入right  if pnt.val < x:  ln.next = ListNode(pnt.val)  ln = ln.next  else:  rn.next = ListNode(pnt.val)  rn = rn.next  pnt = pnt.next   # 將left與right合並  ln.next = right.next  return left.next 

這樣我們固然做了出來,但是我們是在拋棄原鏈表的基礎上做出來的,畢竟開辟了額外的空間。如果我們想要不創建新的鏈表來解決這題應該怎么辦呢?

其實也是很簡單的,我們可以遍歷鏈表,如果發現了大於等於x的元素就將它挪到鏈表的最后。這樣當我們遍歷結束的時候,就完成了鏈表的操作。這個思路雖然簡單,但是在實現的時候有很多坑點,需要特別小心。

比如我們需要一個值來記錄遍歷的重點,因為我們在遍歷的時候可能會將一些元素挪到鏈表的最后。所以我們就不能以None來作為終點了,否則會導致死循環。我們需要以大於等於x的第一個元素作為結束點,當遍歷到了這個位置的時候結束。還有很多其他關於鏈表操作的細節,我們可以來查看代碼:

# Definition for singly-linked list.
# class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution:  def partition(self, head: ListNode, x: int) -> ListNode:  tail = head  if head is None:  return None   # 找到結尾,當找到了大於等於x的元素就放入結尾后面  while tail.next is not None:  tail = tail.next   # 記錄遍歷的終點  end_point = None   pnt = ListNode(0)  pnt.next = head  head = pnt   while pnt.next is not end_point:  cur = pnt.next  if cur.val >= x:  # 插入在末尾  tail.next = cur  tail = cur  # 如果終點是None的話則進行更新  # end_point只會更新一次  if end_point is None:  end_point = cur  pnt.next = cur.next  continue  pnt = pnt.next  tail.next = None  return head.next 

總結

在這題當中,我們面臨的問題是操作鏈表,將鏈表當中的一些元素提取出來放在鏈表最后。無論我們是自己創建新的鏈表來滿足條件,還是在原鏈表的基礎上進行修改,算法的復雜度都是一樣的,只是空間復雜度不同,也因此帶來的編碼復雜度也不同。相對來說,第一種做法更加簡單一些,第二種稍稍復雜,但是也並不難,只要熟悉鏈表的基本操作,應該都是可以做出來的。

關於鏈表相關的問題我們應該已經做了不少了,今天的題目算是很基礎了,相信大家肯定都沒有問題,我也就不再贅述了。

今天的文章到這里就結束了,如果喜歡本文的話,請來一波素質三連,給我一點支持吧(關注、轉發、點贊)。

本文使用 mdnice 排版


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM