LeetCode-86. 分隔链表
题目来源
题目描述
给你一个链表的头节点 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
题解分析
解法一:暴力
- 本题其实题意很好理解,就是将链表分为两部分,在遍历的过程中需要考虑两类节点。
- 这里比较暴力的就是不断遍历链表,然后将小数值的节点不断前移到前面的小节点链表后面。
/**
* Definition for singly-linked list.
* 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) {
ListNode dumyNode = new ListNode(-1);
dumyNode.next = head;
ListNode less = dumyNode;
ListNode now = head, pre = dumyNode;
while(now != null){
if(now.val < x){
if(less.next == now){
less = less.next;
pre = now;
now = now.next;
continue;
}
ListNode next = now.next;
pre.next = next;
// 将当前结点插入到前面的小节点之后
ListNode lessNext = less.next;
now.next = lessNext;
less.next = now;
less = less.next;
now = next;
}else{
pre = now;
now = now.next;
}
}
return dumyNode.next;
}
}
解法二:思维
- 考虑到解法一的步骤十分多,而且在移动链表指针的时候很容易出错,所以这里再仔细考虑题目要求,可以找到另一种更容易的解法。
- 其实题目总结一下就是将一个链表一分为二,分成两个链表。所以,这里我们可以一开始就构造出两个链表头,然后不断遍历原始链表,根据结点值依次拼接到符合条件的链表之后。
/**
* Definition for singly-linked list.
* 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) {
ListNode dumySmall = new ListNode(-1);
ListNode small = dumySmall;
ListNode dumyBig = new ListNode(-1);
ListNode big = dumyBig;
while(head != null){
if(head.val < x){
small.next = head;
small = small.next;
}else{
big.next = head;
big = big.next;
}
head = head.next;
}
big.next = null;
small.next = dumyBig.next;
return dumySmall.next;
}
}
Either Excellent or Rusty