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