初步思路
暴力法:
1. 先遍历一遍链表,统计小于x的数的个数cnt;
2. 链表的前cnt位存储小于x的数,定义俩指针,small指针负责将前cnt位的数,big指针负责后面的数。
3. 若small指针遇到大于等于x的数,big指针遇到小于x的数,则交换这两个数。
c++代码如下:
class Solution {
public:
ListNode* partition(ListNode* head, int x) {//统计小于x的数的个数cnt
ListNode *temp=head;
int cnt=0;
while(temp){
if(temp->val<x) cnt++;
temp=temp->next;
}
ListNode *small=head,*big=head;//设置两个指针,分别指向小于x和大于等于x的数
while(cnt--)
{
big=big->next;
}
while(big)
{
while(cnt--&&small->val<x)
{
small=small->next;
}
while(big&&big->val>=x)
{
big=big->next;
}
if(cnt&&big)//交换
{
int t=small->val;
small->val=big->val;
big->val=t;
}
}
return head;
}
};
思路进阶:双指针(其实为上述方法的精简)
双指针法:
1. 定义两个指针,small、big。
2. small指针落在不小于x的节点上,big向前移动。如果big指针遇到小于x的节点,交换二者的值,然后small指向next。
3. big指针肯定走得更快,所以small指针一直处于不小于x的节点的位置,或者就是两个指针重叠,这时候还是礼貌性地交换一下罢了。
c++代码如下:
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode *small=head,*big=head;//设置两个指针,分别指向小于x和大于等于x的数
while(big)
{
if(big->val<x)//交换
{
int t=small->val;
small->val=big->val;
big->val=t;
small=small->next;
}
big=big->next;
}
return head;
}
};