96 链表划分

原题网址:http://www.lintcode.com/zh-cn/problem/partition-list/

给定一个单链表和数值x,划分链表使得所有小于x的节点排在大于等于x的节点之前。

你应该保留两部分内链表节点原有的相对顺序。

 

样例

给定链表 1->4->3->2->5->2->null,并且 x=3

返回 1->2->2->4->3->5->null

标签 
 
看到这道题懵逼很久,思路一直不清晰,后来码码删删冒出一个想法:
1.可以定义一个ListNode*类型的right,存放大于等于x的节点,即遍历原链表,如果找到大于或等于x的节点,将其赋值给right,结束遍历;
2.然后新建一个链表newList存放小于x的节点,再次遍历原链表,如果当前节点小于x,将其挂载到newList上,再将该节点从原链表中删除,继续遍历下一个节点;
3.最后,将right挂载到newList上。
 
AC代码:
/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param head: The first node of linked list
     * @param x: An integer
     * @return: A ListNode
     */
    ListNode * partition(ListNode * head, int x) {
        // write your code here
         if (head==NULL)
     {
         return NULL;
     }
     ListNode *right=NULL;//大于等于x的第一个节点;
     ListNode *index=head;//保存头结点;
     while(head!=NULL)
     {
         if (head->val>=x)
         {
             right=head;
             break;
         }
         head=head->next;
     }
     ListNode * newList=new ListNode(0);//新链表头结点;
     ListNode *result=newList;
     ListNode *pre=NULL;
     while(index!=NULL)
     {
         if (index->val<x)
         {
             newList->next=new ListNode(index->val);
             newList=newList->next;
             
             //删除index;
             if (pre!=NULL)
             {
                 pre->next=index->next;
             }
             else
             {
                 pre=index;
             }
         }
         else
         {
             pre=index;
         }
         index=index->next;
     }

     newList->next=right;
     return result->next;
    }
};

注意:第2步挂载小于x的节点到newList上时,一定要new出新的节点再挂载,不可直接赋值,如以下代码(通过66%的数据):

           直接赋值的话可能造成错误,当原链表中小于x的节点中间没有间隔时,删除操作也将newList中相同节点删除了……多个指针指向同一个目标的隐患,吐血。
           但如果是例子中给出的1->4->3->2->5->2->null,大于x和小于x的节点间隔开就可以得到正确结果……要警惕测试数据不足时的正确代码啊,哭,指针操作需谨慎。
ListNode * partition(ListNode * head, int x) {
        // write your code here
        if (head==NULL)
     {
         return NULL;
     }
     ListNode *right=NULL;//大于x的第一个节点;
     ListNode *index=head;//保存头结点;
     while(head!=NULL)
     {
         if (head->val>=x)
         {
             right=head;
             break;
         }
         head=head->next;
     }
     ListNode * newList=new ListNode(0);//保存新链表头结点;
     ListNode *result=newList;
     ListNode *pre=NULL;
     while(index!=NULL)
     {
         if (index->val<x)
         {
             newList->next=index;
             newList=index;
             
             //删除index;
             if (pre!=NULL)
             {
                 pre->next=index->next;
             }
             else
             {
                 pre=index;
             }
         }
         else
         {
             pre=index;
         }
         index=index->next;
     }

     newList->next=right;
     return result->next;
    }

最后上网一查发现还有更好的思路,就是标签里的两根指针,参考如下:

https://blog.csdn.net/lfj17/article/details/66590654

https://www.jiuzhang.com/solutions/partition-list/

AC代码:

/**
 * Definition of singly-linked-list:
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *        this->val = val;
 *        this->next = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param head: The first node of linked list
     * @param x: An integer
     * @return: A ListNode
     */
    ListNode * partition(ListNode * head, int x) {
        // write your code here
        if (head==NULL)
    {
        return NULL;
    }
    ListNode * leftDummy=new ListNode(0); //保存头结点;
    ListNode * rightDummy=new ListNode(0);
    ListNode *left=leftDummy;//左侧当前节点;
    ListNode *right=rightDummy;
    while(head!=NULL)
    {
        if (head->val<x)
        {
            left->next=head;
            left=head;
        }
        else
        {
            right->next=head;
            right=head;
        }
        head=head->next;
    }
    right->next=NULL;
    left->next=rightDummy->next;
    return leftDummy->next;
    }
};

 

 

 

posted @ 2018-04-21 20:41  eeeeeeee鹅  阅读(220)  评论(0编辑  收藏  举报