3202 字
约 10 分钟
13
086.分隔链表
无标签

086.分隔链表

作者:沉默王二
发布时间:2023-10-07T15:59:10.872+0800


本题解同时收录在星球专栏《二哥的 LeetCode 刷题笔记》中,专栏托管在语雀平台上(更方便你沉浸式阅读和做笔记),访问地址和密码:https://t.zsxq.com/6iuzn6I

题意

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

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

难度

中等

示例

示例1:

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

示例2:

输入:head = [2,1], x = 2

分析

本题考察的是对链表的遍历和基础操作。

思路其实很简单,遍历一遍链表,然后按照节点元素的大小,将其分别存储到两个链表中,最后再将较大的链表链接到较小的链表,即可完成本题。

题目的难点主要集中在链表的操作上,有时我们常常会被链表的一些基础操作绕晕,要不被绕晕,就要对链表这一基础数据结构烂熟于心。

因为要用两个头节点存放链表的较小元素和较大元素,同时为了防止其中任一链表为空,我们可以这样来实现。

利用smallListHead和largeListHead两个头节点来存储两个链表,然后遍历链表,按照节点大小将节点插入两个链表即可。

最后,记得将存储较大元素的链表尾节点的next设置为null,因为这时的尾节点不一定是原先链表的尾节点,可能会导致我们的最终答案还多出一节。

/**

 * public class ListNode { *     int val; *     ListNode next; *     ListNode() {} *     ListNode(int val) { this.val = val; } *     ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */class Solution {    public ListNode partition(ListNode head, int x) {        // 创建两个新链表,一个用于存放小于 x 的节点,另一个用于存放大于等于 x 的节点        ListNode beforeHead = new ListNode(0), before = beforeHead;  // 小于 x        ListNode afterHead = new ListNode(0), after = afterHead;  // 大于等于 x                while (head != null) {            if (head.val < x) {                before.next = head;                before = before.next;            } else {                after.next = head;                after = after.next;            }            head = head.next;        }
        after.next = null;  // 终止大于等于 x 的链表        before.next = afterHead.next;  // 连接两个链表                return beforeHead.next;  // 返回分割后的链表    }}

我们来模拟一下整个过程。假设我们有以下链表和分隔值:

链表: 1 -> 4 -> 3 -> 2 -> 5 -> 2

步骤 1: 初始化两个临时头节点,beforeHead 和 afterHead。

beforeHead -> [empty list]

步骤 2: 开始遍历链表,根据每个节点的值和 x 的关系,将其添加到对应的临时链表中。

  • 对于值 1,因为它小于 3,我们将其添加到 before 链表。
beforeHead -> 1
  • 对于值 4,因为它大于 3,我们将其添加到 after 链表。
beforeHead -> 1
  • 对于值 3,它等于 x,所以也加入 after 链表。
beforeHead -> 1
  • 对于值 2 (第一个),因为它小于 3,我们将其添加到 before 链表。
beforeHead -> 1 -> 2
  • 同样,对于值 5 和值 2 (第二个) 的处理,我们得到:
beforeHead -> 1 -> 2 -> 2

步骤 3: 将 before 链表的尾部连接到 after 链表的头部。

beforeHead -> 1 -> 2 -> 2 -> 4 -> 3 -> 5

这就是我们想要的结果。

时间复杂度为 (O(n)),其中 (n) 是链表的长度,空间复杂度为 (O(1)),因为我们只是重新排列了链表的节点,没有使用额外的空间来存储数据。

总结

链表作为最基础的,也是大多数小伙伴最早接触的数据结构,必须要烂熟于心。

力扣链接:https://leetcode.cn/problems/partition-list/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 3600 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

本题解同时收录在星球专栏《二哥的 LeetCode 刷题笔记》中,专栏托管在语雀平台上(更方便你沉浸式阅读和做笔记),访问地址和密码:https://t.zsxq.com/6iuzn6I

题意

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

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

难度

中等

示例

示例1:

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

示例2:

输入:head = [2,1], x = 2

分析

本题考察的是对链表的遍历和基础操作。

思路其实很简单,遍历一遍链表,然后按照节点元素的大小,将其分别存储到两个链表中,最后再将较大的链表链接到较小的链表,即可完成本题。

题目的难点主要集中在链表的操作上,有时我们常常会被链表的一些基础操作绕晕,要不被绕晕,就要对链表这一基础数据结构烂熟于心。

因为要用两个头节点存放链表的较小元素和较大元素,同时为了防止其中任一链表为空,我们可以这样来实现。

利用smallListHead和largeListHead两个头节点来存储两个链表,然后遍历链表,按照节点大小将节点插入两个链表即可。

最后,记得将存储较大元素的链表尾节点的next设置为null,因为这时的尾节点不一定是原先链表的尾节点,可能会导致我们的最终答案还多出一节。

/**

 * public class ListNode { *     int val; *     ListNode next; *     ListNode() {} *     ListNode(int val) { this.val = val; } *     ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */class Solution {    public ListNode partition(ListNode head, int x) {        // 创建两个新链表,一个用于存放小于 x 的节点,另一个用于存放大于等于 x 的节点        ListNode beforeHead = new ListNode(0), before = beforeHead;  // 小于 x        ListNode afterHead = new ListNode(0), after = afterHead;  // 大于等于 x                while (head != null) {            if (head.val < x) {                before.next = head;                before = before.next;            } else {                after.next = head;                after = after.next;            }            head = head.next;        }
        after.next = null;  // 终止大于等于 x 的链表        before.next = afterHead.next;  // 连接两个链表                return beforeHead.next;  // 返回分割后的链表    }}

我们来模拟一下整个过程。假设我们有以下链表和分隔值:

链表: 1 -> 4 -> 3 -> 2 -> 5 -> 2

步骤 1: 初始化两个临时头节点,beforeHead 和 afterHead。

beforeHead -> [empty list]

步骤 2: 开始遍历链表,根据每个节点的值和 x 的关系,将其添加到对应的临时链表中。

  • 对于值 1,因为它小于 3,我们将其添加到 before 链表。
beforeHead -> 1
  • 对于值 4,因为它大于 3,我们将其添加到 after 链表。
beforeHead -> 1
  • 对于值 3,它等于 x,所以也加入 after 链表。
beforeHead -> 1
  • 对于值 2 (第一个),因为它小于 3,我们将其添加到 before 链表。
beforeHead -> 1 -> 2
  • 同样,对于值 5 和值 2 (第二个) 的处理,我们得到:
beforeHead -> 1 -> 2 -> 2

步骤 3: 将 before 链表的尾部连接到 after 链表的头部。

beforeHead -> 1 -> 2 -> 2 -> 4 -> 3 -> 5

这就是我们想要的结果。

时间复杂度为 (O(n)),其中 (n) 是链表的长度,空间复杂度为 (O(1)),因为我们只是重新排列了链表的节点,没有使用额外的空间来存储数据。

总结

链表作为最基础的,也是大多数小伙伴最早接触的数据结构,必须要烂熟于心。

力扣链接:https://leetcode.cn/problems/partition-list/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 3600 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

本题解同时收录在星球专栏《二哥的 LeetCode 刷题笔记》中,专栏托管在语雀平台上(更方便你沉浸式阅读和做笔记),访问地址和密码:https://t.zsxq.com/6iuzn6I

题意

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

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

难度

中等

示例

示例1:

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

示例2:

输入:head = [2,1], x = 2

分析

本题考察的是对链表的遍历和基础操作。

思路其实很简单,遍历一遍链表,然后按照节点元素的大小,将其分别存储到两个链表中,最后再将较大的链表链接到较小的链表,即可完成本题。

题目的难点主要集中在链表的操作上,有时我们常常会被链表的一些基础操作绕晕,要不被绕晕,就要对链表这一基础数据结构烂熟于心。

因为要用两个头节点存放链表的较小元素和较大元素,同时为了防止其中任一链表为空,我们可以这样来实现。

利用smallListHead和largeListHead两个头节点来存储两个链表,然后遍历链表,按照节点大小将节点插入两个链表即可。

最后,记得将存储较大元素的链表尾节点的next设置为null,因为这时的尾节点不一定是原先链表的尾节点,可能会导致我们的最终答案还多出一节。

/**

 * public class ListNode { *     int val; *     ListNode next; *     ListNode() {} *     ListNode(int val) { this.val = val; } *     ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */class Solution {    public ListNode partition(ListNode head, int x) {        // 创建两个新链表,一个用于存放小于 x 的节点,另一个用于存放大于等于 x 的节点        ListNode beforeHead = new ListNode(0), before = beforeHead;  // 小于 x        ListNode afterHead = new ListNode(0), after = afterHead;  // 大于等于 x                while (head != null) {            if (head.val < x) {                before.next = head;                before = before.next;            } else {                after.next = head;                after = after.next;            }            head = head.next;        }
        after.next = null;  // 终止大于等于 x 的链表        before.next = afterHead.next;  // 连接两个链表                return beforeHead.next;  // 返回分割后的链表    }}

我们来模拟一下整个过程。假设我们有以下链表和分隔值:

链表: 1 -> 4 -> 3 -> 2 -> 5 -> 2

步骤 1: 初始化两个临时头节点,beforeHead 和 afterHead。

beforeHead -> [empty list]

步骤 2: 开始遍历链表,根据每个节点的值和 x 的关系,将其添加到对应的临时链表中。

  • 对于值 1,因为它小于 3,我们将其添加到 before 链表。
beforeHead -> 1
  • 对于值 4,因为它大于 3,我们将其添加到 after 链表。
beforeHead -> 1
  • 对于值 3,它等于 x,所以也加入 after 链表。
beforeHead -> 1
  • 对于值 2 (第一个),因为它小于 3,我们将其添加到 before 链表。
beforeHead -> 1 -> 2
  • 同样,对于值 5 和值 2 (第二个) 的处理,我们得到:
beforeHead -> 1 -> 2 -> 2

步骤 3: 将 before 链表的尾部连接到 after 链表的头部。

beforeHead -> 1 -> 2 -> 2 -> 4 -> 3 -> 5

这就是我们想要的结果。

时间复杂度为 (O(n)),其中 (n) 是链表的长度,空间复杂度为 (O(1)),因为我们只是重新排列了链表的节点,没有使用额外的空间来存储数据。

总结

链表作为最基础的,也是大多数小伙伴最早接触的数据结构,必须要烂熟于心。

力扣链接:https://leetcode.cn/problems/partition-list/

一步一个脚印

不积跬步无以至千里,不积小流无以成江海。LeetCode - 100天从算法小白到卷王正式启动了,我们计划周一到周五至少每天更新一篇,周六周日更新一篇,目标 300 道 LeetCode 经典题。

PDF 版本目前只针对**二哥编程星球 的球友开放,如果你也想一起打卡学习算法的话,戳链接 **加入我们吧。

一个人可以走得很快,但一群人才能走得更远。二哥编程星球 (目前已有 3600 多名球友加入)里面的每个球友都非常的友善,除了鼓励你,还会给你提出合理的建议,一起冲!

            知识星球
            
    
    
        
        扫码加入星球
        查看更多优质内容
    
    https://wx.zsxq.com/mweb/views/joingroup/join_group.html?group_id=15522885221412
086.分隔链表
https://clxhxhhr.top/posts/2540/
作者
clxstart
发布于
2026-09-19
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。
☰ 文章目录