zoukankan      html  css  js  c++  java
  • 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;
        }
    };
  • 相关阅读:
    Remove Duplicates from Sorted List II [LeetCode]
    Valid Palindrome [LeetCode]
    Merge Sorted Array [LeetCode]
    Binary Tree Postorder Traversal
    Subsets [LeetCode]
    Search for a Range [LeetCode]
    Reorder List [LeetCode]
    GCC 默认用哪个标准
    18 组装类举例
    17 实例方法、静态方法、类方法
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/8903615.html
Copyright © 2011-2022 走看看