[LeetCode] Partition List

2014-11-24 02:24:11 · 作者: · 浏览: 1
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
问题描述:给定一个单链表和一个值x,将这个链表进行划分,使得小于这个值x的节点在大于或者等于x的节点的前面,而且必须保证这些节点在链表中的相对顺序。
这题可以这样简单的思考:找到第一个比3大于或者等于的,然后把该节点后面小于3的节点插入到它的前面。比如这里,找到4,后面是3,继续遍历,找到2,把2取下,插入到4前面,再往后是5,继续遍历,找到2,把2取下,插入到4前面。
想法是这样,但是在编写代码的时候要处理很多细节问题,比如,要取下小于x的节点,那么就要保存该节点的前面的节点的指针,必然要用两个指针进行遍历,另一方面,当第一个是大于或者等于x的节点和当第一个是小于x的节点的处理方式也不一样。
代码中设置了5个变量:
(1)ListNode *p 遍历的当前节点的前面的节点
(2)ListNode *q 遍历的当前节点
(3) ListNode *r 指向第一个大于或者等于x的节点
(4) bool set r是否指向了第一个大于或者等于x的节点
(5) bool first 是否是第一次遍历,因为第一次遍历的行为和后面额行为主要差别在于p节点是否移动。
因为有些情况实在不好进行合并,因此基本都进行了分类讨论。
class Solution {  
public:  
    ListNode *partition(ListNode *head, int x) {  
        // IMPORTANT: Please reset any member data you declared, as  
        // the same Solution instance will be reused for each test case.  
        ListNode *p = head, *q = head, *r = NULL;  
        bool set = false, first = true;  
  
        while(q) {  
            if(!first) {  
                if(q->val >= x && !set) {  
                    r = p;  
                    p = q;  
                    q = q->next;  
                    set = true;  
                }  
                else if(q->val < x && set) {  
                    p->next = q->next;  
                    if(r == head && r->val >= x) {  
                        q->next = head;  
                        head = q;  
                        r = head;  
                    }  
                    else {  
                        q->next = r->next;  
                        r->next = q;  
                        r = q;  
                    }  
                    q = p->next;  
                }  
                else {  
                    p = q;  
                    q = q->next;  
                }               
            }  
            else {  
                if(q->val >= x) {  
                    r = q;  
                    q = q->next;  
                    set = true;  
                }  
                else  
                    q = q->next;  
                first = false;  
            }  
        }  
  
        return head;  
    }  
};