每日一题(LeetCode)----链表–分隔链表
1.题目(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
2.解题思路
思路一
将这个链表进行拆分,然后合并
1.拆分
把比目标值小的节点存一个链表里,把比目标值大的节点另一个链表里
2.合并
把存比目标值大的节点的链表接到存比目标值小的节点的链表的后面
思路二:快排的思想:区间分割法
1.申请一个虚拟节点,且这个虚拟节点指向头节点,然后这个虚拟节点作为小区间(比目标值小的节点的空间)的尾节点
2.遍历链表进行节点的改变来得到所要的答案链表
遍历链表,看当前链表中的值是否小于目标值
如果大于,那么pre指向当前节点,然后继续遍历
如果小于,那么看pre所指向的节点是否是小区间的尾节点
如果是,那么pre指向当前节点,然后继续遍历
如果不是 ,(1)我们让pre指向的那个节点的下一个节点变为为当前节点的下一个节点
(2)当前节点指向小区间尾节点的下一个节点,然后小区间的尾节点再指向当节点 (3)小区间的尾节点向后移动一个节点,下一次要遍历的节点为pre所指向节点的下一个节点
3.写出代码
思路一的代码
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if(head==nullptr||head->next==nullptr){
return head;
}
//遍历一遍链表拆成两个链表
ListNode* head1=nullptr;
ListNode* head2=nullptr;
ListNode* tail1=nullptr;
ListNode* tail2=nullptr;
while(head){
if(head->val<x){
if(head1==nullptr){
head1=tail1=head;
}
else{
tail1->next=head;
tail1=tail1->next;
}
}
else{
if(head2==nullptr){
head2=tail2=head;
}
else{
tail2->next=head;
tail2=tail2->next;
}
}
head=head->next;
}
if(tail1){
tail1->next=nullptr;
}
if(tail2){
tail2->next=nullptr;
}
if(tail1){
tail1->next=head2;
return head1;
}
else{
return head2;
}
}
};
思路二的代码
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if(head ==nullptr || head->next==nullptr){
return head;
}
ListNode* dummyhead = new ListNode(0,head);
ListNode* prevtail = dummyhead,*prev = dummyhead,*curr = head;
while(curr){
if(curr->val < x){
if(prev != prevtail){
prev->next = curr->next;
curr->next = prevtail->next;
prevtail->next = curr;
prevtail = prevtail->next;
curr = prev->next;
}else{
prev = prevtail = curr;
curr = curr->next;
}
}else{
prev = curr;
curr = curr->next;
}
}
return dummyhead->next;
}
};