题目描述
给你一个链表的头节点 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 通过次数27,373提交次数
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/pa… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
直接利用重排列表的思想,把所有节点打散,再按照需求重新排列
- 遍历链表,把节点都储存到数组中
- 创建一个虚拟节点newNode作为要返回的重排的链表头部
- 再遍历节点数组,把小于x的节点按照顺序,排在新链表后面
- 再遍历一次链表,把大于等于x的节点排在新链表后面
- 返回newNode.next
以上方法总共遍历3次,然后思考了下,优化成遍历两次
第一次不变,第二次和第三次同时进行
- 思路就是,加入一个记录中间节点,中间节点定义为新链表中,最后一个小于x的元素,若没有,头部节点就是中间节点
- 然后遍历的时候,小于x的节点往中间节点后面插图,并刷新中间节点
- 大于等于x的元素直接往末尾插,并刷新记录的最后一个节点
- 注意,当还没有遍历到过大于等于x元素的时候,最后一个节点就是中心节点,所以需要刷新最后一个节点
代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function(head, x) {
let current=head;
let list=[];//储存节点
while(current){
list.push(current);
current=current.next;
}
let result=new ListNode(0,null);
let lastNode=result;
let centerNode=lastNode;
let isMore=false;
for(let i=0;i<list.length;i++){
list[i].next=null;
if(list[i].val<x){
//小于x的节点插入分割节点后面
let next=centerNode.next;//保存原本的next节点
centerNode.next=list[i];//添加到分隔节点后
centerNode=list[i];//刷新中间节点
centerNode.next=next;//把原本的next节点放到现在的节点后面,实现中间插入节点
if(!isMore){
//如果从没遍历到过大于x的元素,则lastNode就是centerNode
lastNode=centerNode;//记录新链表的末尾
}
}else{
//大于x的节点插入链表末尾
lastNode.next=list[i];//添加到新链表的末尾
lastNode=list[i];//记录新链表的末尾
isMore=true;
}
}
return result.next;
};