CC11:链表分割
题目
编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前
给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。
解法
这道题自己最初的思路是这样的,首先找到给定值x的那个节点为px,然后按下图所示的方法进行操作:
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
// write code here
if(pHead==NULL || pHead->next==NULL)
return pHead;
ListNode* px=pHead;
ListNode* p1=pHead;
ListNode* p2=pHead->next;
while(px!=NULL)
{
if(px->val==x)
break;
}
while(p2->next!=NULL)
{
if(p2->val>x)
{
p1->next=p2->next;
p2->next=px->next;
px->next=p2;
p1=p1->next;
p2=p1->next;
}
p1=p1->next;
p2=p2->next;
}
}
};
但是这样的做法有几个错误,第一个,题目要求的是给定值x为基准进行分割,并没有说这个x一定是某个绩点,这样子的话就会找不到x这个节点;第二个错误是,这个算法只能将大于x的节点调到节点x之后,在x节点之后如果存在小于x的节点是无法移动到前面的,这是由于链表的单向指向性。所以这个思路完全是不可用的!!
更改解法:
创建两个新链表,一个存小的、一个存大的;最后将小的和大的拼接起来就OK了。键代码:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
// write code here
if(pHead==NULL || pHead->next==NULL)
return pHead;
ListNode* pNode=pHead;
ListNode* small=new ListNode(0);
ListNode* big=new ListNode(0);
ListNode* p1=small;
ListNode* p2=big;
while(pNode!=NULL)
{
if(pNode->val<x)
{
p1->next=pNode;
pNode=pNode->next;
p1=p1->next;
p1->next=NULL;
}
else
{
p2->next=pNode;
pNode=pNode->next;
p2=p2->next;
p2->next=NULL;
}
}
p1->next=big->next;
return small->next;
}
};
另外一种类似的方法,不用创建两个链表,而是创建一个链表,原链表如果小于x就加入到新链表并将原链表这个节点删去。最后就爱那个两个链表连接起来就可以了:
class Solution{
public:
LinkList partition(LinkList L,int key)
{
LinkList L1=(LinkList)malloc(sizeof(LNode));
LinkList q=L1;
LinkList cur=L;
while(cur->next)
{
cur=cur->next;
if(cur->next->data<key)
{
LinkList p=cur->next;
cur->next=p->next;
q->next=p;
q=p;
}
}
q->next=L->next;
free(L);
}
};
作者:YunLambert
-------------------------------------------
个性签名:一名会音乐、爱健身的不合格程序员
可以Follow博主的Github哦(っ•̀ω•́)っ✎⁾⁾