86.分隔链表
因为对链表中的一个节点进行更换位置的操作需要知道该节点的上一个节点
所以建立一个虚拟头节点
cpp
ListNode* p=new ListNode(-201,head);
根据题意,我们需要找到第一个大于x或等于x的节点large
并且将第一个大于或等于x的节点large后的所有小于x的节点都挪到large前
但是在代码里为了方便挪动节点位置,large为第一个大于x的节点的前一个节点
首先我们要找到第一个大于或等于x的节点
cpp
ListNode* p=new ListNode(-201,head);
ListNode* large=p;
ListNode* cur=p;
int flag=0;
while(cur->next)
{
if(cur->next->val>=x&&flag==0)
{
large=cur;
flag=1;
}
cur=cur->next;
}
然后再从large后第一个节点开始找,找那些小于x的节点,并挪到large前
这一步要分三个情况
- 当前节点cur大于等于x,cur指向下一个节点
- 当前节点cur小于x,且当前节点不是链表最后一个节点,正常挪
- 当前节点cur小于x,且当前节点是链表最后一个节点,这个时候指针变换时有一个会指向nullptr,要特别写出来
cpp
cur=large->next;
while(cur&&cur->next)
{
if(cur->next->val<x&&cur->next->next)
{
ListNode* temp1=large->next;
ListNode* temp2=cur->next->next;
large->next=cur->next;
cur->next->next=temp1;
cur->next=temp2;
large=large->next;
}
else if(cur->next->val<x&&cur->next->next==nullptr)
{
ListNode* temp1=large->next;
large->next=cur->next;
cur->next->next=temp1;
cur->next=nullptr;
large=large->next;
}
else
cur=cur->next;
}
return p->next;
最后增加一些边界条件
cpp
if(head==nullptr||head->next==nullptr)
return head;
if(flag==0)//如果找不到大于x的节点
{
return p->next;
}
整合起来
cpp
/**
* 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* p=new ListNode(-201,head);
ListNode* large=p;
ListNode* cur=p;
int flag=0;
if(head==nullptr||head->next==nullptr)
return head;
while(cur->next)
{
if(cur->next->val>=x&&flag==0)
{
large=cur;
flag=1;
}
cur=cur->next;
}
if(flag==0)//如果找不到大于x的节点
{
return p->next;
}
cur=large->next;
while(cur&&cur->next)
{
if(cur->next->val<x&&cur->next->next)
{
ListNode* temp1=large->next;
ListNode* temp2=cur->next->next;
large->next=cur->next;
cur->next->next=temp1;
cur->next=temp2;
large=large->next;
}
else if(cur->next->val<x&&cur->next->next==nullptr)
{
ListNode* temp1=large->next;
large->next=cur->next;
cur->next->next=temp1;
cur->next=nullptr;
large=large->next;
}
else
cur=cur->next;
}
return p->next;
}
};
不过
其实第二步,从large后开始找小于x的数,完全可以合到第一步的循环里做
这部分需要再优化一下