leetcode Partition List二分鏈表問題

leetcode medium:Partition List 問題

  • 1.題目概要
  • 2.知識點梳理及解答
  • 3.總結

1.題目概要
給定已知鏈表和一個值x,將其分成兩個部分,讓所有小於x的值在鏈表的前半部分,大於或者的值在後半部分,題目要求不允許改變原來鏈表的有序特性,例子如下:
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
2.知識點梳理及解答
2.1知識點梳理
此題目涉及的鏈表知識點有:
①鏈表歸併
此類操作是將滿足某一特性的鏈表結點歸併成一個或者幾個鏈表,最爲常見的題目爲:leetcode的Merge Two Sorted Lists兩個有序鏈表歸併爲一個有序鏈表:
代碼如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) 
    {
        ListNode* head=NULL;
        if(!l1)
            return l2;
        if(!l2)
            return l1;
        if(!l1&&!l2)
            return NULL;
        if(l1->val<=l2->val)
           head=l1;
        else
           head=l2;
        merge(l1,l2);
        return head;
    }
    ListNode* merge(ListNode*l1,ListNode*l2)
    {
        if(!l1)
            return l2;
        if(!l2)
            return l1;
        if(l1->val<=l2->val)
        {
            l1->next=merge(l1->next,l2);
        }
        else
        {
            l2->next=merge(l1,l2->next);
        }
    }
};

②鏈表查找
此類操作是將關於某個結點或者其屬性值的找到,並將其刪除。leetcode Delete Node in a Linked List如果沒有頭結點,但是要刪除某個特定的結點的題目:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) 
    {
        node->val=node->next->val;
        ListNode* temp=node->next;
        node->next=temp->next;
        delete temp;
    }
};

③鏈表拆分
此類操作主要目的是服務於鏈表的合併。
2.2解答
解題思路:
step one:將此鏈表依照2.1拆分的知識點綜述分成兩部分,即構建兩個鏈表
step two:將兩個鏈表合併成一個鏈表
形象化描述:分久必合,合久必分-服務於自然之法
方法技巧:這裏我構建了兩個頭結點,以便統一操作方便。
代碼如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *partition(ListNode *head, int x) {
        if(!head||!head->next)
            return head;
        ListNode*large=new ListNode(0);
        ListNode*small=new ListNode(0);
        ListNode*current=head;
        ListNode*s=small;
        ListNode*l=large;
        while(current)
        {
            if(current->val>=x)
            {
                l->next=current;
                l=l->next;
            }
            else
            {
                s->next=current;
                s=s->next;
            }
            current=current->next;
        }
        s->next=l->next=NULL;
        s->next=large->next;
        return small->next;
    } 
};

3.總結
從上面的一些題目我們可以看出:①鏈表的歸併與拆分分不開②鏈表的頭結點的的設置不失爲解決問題的好方法(沒有設置頭結點操作很多不統一)③問題的方法及特殊技巧需要平時一點一滴的積累;讓我們一同努力,明天會更好!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章