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.总结
从上面的一些题目我们可以看出:①链表的归并与拆分分不开②链表的头结点的的设置不失为解决问题的好方法(没有设置头结点操作很多不统一)③问题的方法及特殊技巧需要平时一点一滴的积累;让我们一同努力,明天会更好!

你可能感兴趣的:(leetcode)