CC11:链表分割

题目

编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前
给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。

解法

这道题自己最初的思路是这样的,首先找到给定值x的那个节点为px,然后按下图所示的方法进行操作:
图片.png

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);
	}
}; 
posted @ 2018-07-07 20:55  MrYun  阅读(187)  评论(0编辑  收藏  举报