86. 分隔链表 - 力扣(LeetCode)
文章更新:2021年10月22日20:42:55
问题描述及示例
给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。
示例 1:
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
示例 2:
输入:head = [2,1], x = 2
输出:[1,2]
提示:
链表中节点的数目在范围 [0, 200] 内
-100 <= Node.val <= 100
-200 <= x <= 200
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的题解
链表的题往往要用到指针的思想,这句话我说过好几次了,目前我做的好几道链表题都是用各种指针来标识节点和辅助遍历之类的。这里的所谓指针其实就是一个保存节点对象内存地址的一个变量。
这道题也是一样的套路,也是用指针来保存节点地址和辅助遍历链表。其中 p
指针用于遍历链表。deleted
指针则是用于标识要从原链表中删除的节点。而 rear
指针则用于标识 lessThanX
链表的尾部。
大体思路如下:
- 先创建一个辅助链表
lessThanX
用于按序存储那些节点值小于x
的节点。 - 用
p
指针遍历链表,如果当前遍历的节点的节点值小于x
,则将该节点从链表中暂时删除,并用一个deleted
指针保存这个节点。 - 将上述被删除的节点链接到
lessThanX
链表的尾部。 - 原链表遍历完成后,
lessThanX
中就存储了那些节点值小于x
的节点。而且这些节点的相对位置和其在原链表的相对位置是一样的。 - 将原链表的剩余节点链接到
lessThanX
链表的尾部即可。
注意,因为涉及到要从链表中删除一个节点,所以遍历原链表时,p
指针指向的是当前遍历节点的前一个节点。
而且,为了方便表示,我给原链表和辅助用的 lessThanX
链表都加上了一个辅助头节点。
详解请看下方注释:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function(head, x) {
// dummy是给原链表加的辅助头节点
let dummy = new ListNode(0, head);
// lessThanX是用于存储节点值小于x的节点的辅助链表,
// 其中lessThanX也可以看做是该链表的辅助头结点
let lessThanX = new ListNode(0, null);
// rear用于标识lessThanX的表尾,方便我们给它添加节点
let rear = lessThanX;
// p指针用于遍历原链表,其初始指向为辅助头结点dummy,
// 但是因为我们遍历的当前节点为p.next,所以实际上遍历的起点为原链表的头节点
let p = dummy;
// deleted用于标识要从原链表中删除的节点
let deleted = null;
// 如果当前遍历节点不为空,则继续往下遍历
while(p.next) {
// 如果当前遍历节点的节点值小于x,
if(p.next.val < x) {
// 则让deleted指针标识该节点
deleted = p.next;
// 改变p指针所指向的节点的next域已达到从原链表中删除当前遍历节点的效果
p.next = p.next.next;
// 设置当前节点的next域为空
deleted.next = null
// 将被删除的节点链接到lessThanX的尾部
rear.next = deleted;
rear = rear.next;
// 因为有一个节点被从原链表中删除了,所以出现了类似数组塌陷的效果,
// 此时应该立即进入下一次遍历
continue;
}
// 如果当前遍历节点的节点值大于等于x,则让该节点保持原位,开始下一次遍历
p = p.next;
}
// 当原链表被遍历完后,lessThanX中存储的节点的节点值就是小于x的
// 将原链表剩余的节点链接到lessThanX中的尾部
rear.next = dummy.next;
// 将重新拼接后的链表返回,注意不要包含辅助头结点
return lessThanX.next;
};
提交记录
168 / 168 个通过测试用例
状态:通过
执行用时:72 ms, 在所有 JavaScript 提交中击败了77.13%的用户
内存消耗:39.1 MB, 在所有 JavaScript 提交中击败了79.60%的用户
时间:2021/10/22 20:57
官方题解
更新:2021年7月29日18:43:21
因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。
更新:2021年10月22日20:48:13
【更新结束】
有关参考
暂无