给你一个链表的头节点 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.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if(!head||!head->next)
return head;
ListNode* dummtNode=new ListNode(0,head);
ListNode* pre=dummtNode,* cur=head;
while(cur&&cur->val<x){
pre=cur;
cur=cur->next;
}
while(cur&& cur->next){
if(cur->next->val<x){
ListNode* insert=cur->next;
cur->next=cur->next->next;
insert->next=pre->next;
pre->next=insert;
pre=insert;
}else{
cur=cur->next;
}
}
return dummtNode->next;
}
};
这段代码的思路是将链表分为两段,一段是小于x的节点,一段是大于等于x的节点。维护两个指针pre
和cur
,其中pre
指向小于x的最后一个节点,cur
指向当前遍历的节点。
首先创建一个虚拟节点dummyNode
,将其next指向原链表的头节点head
,以便处理头节点小于x的情况。
然后通过一个循环,找到第一个大于等于x的节点,将pre
指向该节点的前一个节点,将cur
指向该节点。
接下来再通过一个循环,如果当前节点的下一个节点小于x,则将该节点插入到pre
节点和pre
节点的下一个节点之间,并更新pre
的位置。如果当前节点的下一个节点大于等于x,则将cur
指针指向下一个节点。
最后返回dummyNode
节点的next即可得到分隔后的链表。
解法二:用辅助链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* small=new ListNode(0),*smallhead=small,*large=new ListNode(0),*largehead=large;
while(head!=nullptr){
if(head->val<x){
small->next=head;
small=small->next;
}
else{
large->next=head;
large=large->next;
}
head=head->next;
}
large->next=nullptr;
small->next=largehead->next;
return smallhead->next;
}
};
这段代码的思路是使用两个新的链表,一个用来存储小于x的节点,一个用来存储大于等于x的节点。同时使用两个指针small
和large
,分别指向两个链表的最后一个节点。
首先创建两个新的链表,small
用于存储小于x的节点,smallhead
用于记录头节点,large
用于存储大于等于x的节点,largehead
用于记录头节点。
然后通过一个循环遍历原链表的所有节点。如果当前节点的值小于x,则将其加入到small
链表中,并更新small
的位置。如果当前节点的值大于等于x,则将其加入到large
链表中,并更新large
的位置。
最后将large
链表的最后一个节点指向nullptr,将small
链表的最后一个节点指向largehead
的第一个节点。
返回smallhead
的next即可得到分隔后的链表。