[路飞]_分隔链表

230 阅读2分钟

「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

题目

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例 1:

image.png

输入: head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

力扣(LeetCode)链接:leetcode-cn.com/problems/pa…

解题思路

  1. 第一眼看完题就想着遍历一遍,找到把小于 x 的节点从原位置删除,加到前面。但是题目有要求保留每个节点原有的相对位置,所以不能这么干。
  2. 那就创建个新的链表,把小于 x 的节点放到新链表上,再把两个子链表拼接后返回。
  3. 既然小于 x 的那部分节点可以放到新链表上。那大于的那部分也可以放新链表上,这样省去了删除的操作,逻辑也更清晰,只是多了个头节点,和节点引用。
  4. 从主链表删除节点并添加到新链表操作步骤:
    • 子链表尾节点指向新节点
    • 遍历的指针后移
    • 子链表尾节点后移
    • 设置子链表尾节点的 next 为 null

代码实现

var partition = function(head, x) {
  let largeHead = new ListNode(null, null)
  let smallHead = new ListNode(null, null)
  let largeEnd = largeHead //当前较大链表尾节点,默认指向大链表的头
  let samllEnd = smallHead //当前较小链表尾节点,默认指向小链表的头
  let curr = head

  while (curr) {
    if (curr.val < x) {
      //当前节点的值小于x时
      //1.当前节点加到较小链表的尾部
      //2.较小链表尾节点后移
      samllEnd.next = curr
      samllEnd = samllEnd.next
    } else {
      largeEnd.next = curr
      largeEnd = largeEnd.next
    }
    curr = curr.next
  }

  //更新最大尾节点的 next 为 null,防止出现环
  largeEnd.next = null
  //把小链表的最后一个节点指向大链表真实的头节点
  samllEnd.next = largeHead.next
  return smallHead.next
}

如有错误欢迎指出,欢迎一起讨论!