题目
面试题 02.04. 分割链表
给你一个链表的头节点 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]
思路1:
- 定义一个两个伪头节点,一个little,一个larger,这个两个节点放着不动,用来记录两个分割链表的头节点。
- 定义两个指针节点littleHead = little,largerHead = larger
- 遍历链表,遇到小于x的值则让littlehead指向它,遇到大于等于x的值,则让largerHead指向它,
- 最后让littleHead的next指向larger的next,largerHead 要指向null
代码如下:
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function(head, x) {
let little = new ListNode(0);
let larger = new ListNode(0);
let littleHead = little;
let largerHead = larger;
while(head){
if(head.val <x){
littleHead.next = head
littleHead = head;
}else{
largerHead.next = head;
largerHead = head
}
head = head.next;
}
largerHead.next = null;
littleHead.next = larger.next;
return little.next;
};
思路2:
俗称头插法。遍历链表,遇到大于x节点的则不动,遇到小于x的节点,则将节点移动到头部,这样能保证最终所有小于x的节点都在大于x的左边,并且没有刻意保持链表的相对位置。
这个方法就是要注意做好pre节点的处理。
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function(head, x) {
if(head==null) return null;
let dummy=new ListNode(0);
dummy.next=head;
let pre = head;
head = head.next;
while(head!=null){
if(head.val<x){
pre.next=head.next;
head.next=dummy.next;
dummy.next=head;
head=pre.next;
}else{
pre=pre.next;
head=head.next;
}
}
return dummy.next;
};