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