Movatterモバイル変換


[0]ホーム

URL:


CtrlK
在本页

0086. 分隔链表

题目地址(86. 分隔链表)

https://leetcode-cn.com/problems/partition-list/

题目描述

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。 示例:输入: head = 1->4->3->2->5->2, x = 3输出: 1->2->2->4->3->5

前置知识

  • 链表

公司

  • 阿里

  • 腾讯

  • 百度

  • 字节

思路

  • 设定两个虚拟节点,dummyHead1 用来保存小于该值的链表,dummyHead2 来保存大于等于该值的链表

  • 遍历整个原始链表,将小于该值的放于 dummyHead1 中,其余的放置在 dummyHead2 中

遍历结束后,将 dummyHead2 插入到 dummyHead1 后面

86.partition-list

(图片来自: https://github.com/MisterBooo/LeetCodeAnimation)

关键点解析

  • 链表的基本操作(遍历)

  • 虚拟节点 dummy 简化操作

  • 遍历完成之后记得currentL1.next = null;否则会内存溢出

如果单纯的遍历是不需要上面操作的,但是我们的遍历会导致 currentL1.next 和 currentL2.next 中有且仅有一个不是 null, 如果不这么操作的话会导致两个链表成环,造成溢出。

代码

  • 语言支持: Javascript,Python3, CPP

/** * @param {ListNode} head * @param {number} x * @return {ListNode} */var partition = function (head, x) {  const dummyHead1 = {    next: null,  };  const dummyHead2 = {    next: null,  };  let current = {    next: head,  };  let currentL1 = dummyHead1;  let currentL2 = dummyHead2;  while (current.next) {    current = current.next;    if (current.val < x) {      currentL1.next = current;      currentL1 = current;    } else {      currentL2.next = current;      currentL2 = current;    }  }  currentL2.next = null;  currentL1.next = dummyHead2.next;  return dummyHead1.next;};

Python3 Code:

class Solution:    def partition(self, head: ListNode, x: int) -> ListNode:        """在原链表操作,思路基本一致,只是通过指针进行区分而已"""        # 在链表最前面设定一个初始node作为锚点,方便返回最后的结果        first_node = ListNode(0)        first_node.next = head        # 设计三个指针,一个指向小于x的最后一个节点,即前后分离点        # 一个指向当前遍历节点的前一个节点        # 一个指向当前遍历的节点        sep_node = first_node        pre_node = first_node        current_node = head        while current_node is not None:            if current_node.val < x:                # 注意有可能出现前一个节点就是分离节点的情况                if pre_node is sep_node:                    pre_node = current_node                    sep_node = current_node                    current_node = current_node.next                else:                    # 这段次序比较烧脑                    pre_node.next = current_node.next                    current_node.next = sep_node.next                    sep_node.next = current_node                    sep_node = current_node                    current_node = pre_node.next            else:                pre_node = current_node                current_node = pre_node.next        return first_node.next

CPP Code:

class Solution {public:    ListNode* partition(ListNode* head, int x) {        ListNode dummy, geHead, *ltTail = &dummy, *geTail = &geHead;        while (head) {            auto p = head;            head = head->next;            if (p->val < x) {                ltTail->next = p;                ltTail = p;            } else {                geTail->next = p;                geTail = p;            }        }        ltTail->next = geHead.next;        geTail->next = NULL;        return dummy.next;    }};

复杂度分析

  • 时间复杂度:$O(N)$

  • 空间复杂度:$O(1)$

大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。 大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。

最后更新于

这有帮助吗?


[8]ページ先頭

©2009-2025 Movatter.jp