Partition List

题目初看上去比较绕,感觉有很多情况需要处理,这时就需要仔细分析问题的本质,

尽量将问题归一化。

首先根据题目的要求,比x小的元素的移动参考标准其实很固定,只需要参考链表中第一个

大于或等于x的元素记为first。线性扫描链表,依次将小于x的节点移动到first之前就可以了。

所以这里我们需要记录first的前缀节点,以及当前节点的前缀节点。

另外还有一种特殊情况,也就是头结点head的值大于或等于x。此时需要单独处理,直到head前插入了一个

小节点后,就转化为了前一种情况。

代码写得比较乱,以后会集中整理

/**
 * 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 == NULL)
            return head;
        int count = 0;
        ListNode *truehead = head;
        ListNode *first = NULL;
        ListNode *nextToFirst;
        ListNode *current;
        ListNode *nextToCurrent;
        ListNode *temp;
        nextToCurrent = head;
        current = head->next;
        if(head->val >=x)
        {

            while(current != NULL)
            {
                if(current->val < x)
                {
                    temp = current->next;
                    current->next = head;
                    nextToCurrent->next = temp;
                    truehead = current;
                    current = nextToCurrent->next;
                    count++;
                    first = head;
                    nextToFirst = truehead;
                    break;
                }
                else
                {
                    nextToCurrent = current;
                    current = current->next;

                }
            }
        }


        while(current != NULL)
        {
            if(current->val >= x)
            {
                count++;
                if(count == 1)
                {
                    first = current;
                    nextToFirst = nextToCurrent;
                }
                nextToCurrent = current;
                current = current->next;
            }
            else
            {
                if(first != NULL)
                {
                    temp = current->next;
                    nextToFirst->next = current;
                    current->next = first;
                    nextToFirst = current;
                    current = temp;
                    nextToCurrent->next = current;
                }
                else
                {
                    nextToCurrent = current;
                    current = current->next;
                }
            }
        }

        return truehead;
    }
};

另外一种思路是重新生成两个链表,分别代表大于等于x和小于x的部分,然后将两个表拼接起来,

这种方法,实现起来非常简单,但是需要申请额外的存储空间

class Solution {  
public:  
    ListNode *partition(ListNode *head, int x) {  
        // Start typing your C/C++ solution below  
        // DO NOT write int main() function  
        if (head == NULL) return NULL;  
          
        ListNode* a = new ListNode(0);  
        ListNode* pSmall = a;  
        ListNode* b = new ListNode(0);  
        ListNode* pLarge = b;  
          
        while(head != NULL)  
        {  
            if (head->val < x)  
            {  
                pSmall->next = head;  
                pSmall = head;  
                head = head->next;  
            }  
            else  
            {  
                pLarge->next = head;  
                pLarge = head;  
                head = head->next;  
            }  
        }  
          
        pLarge->next = NULL;  
        pSmall->next = b->next;  
        return a->next;  
    }  
};  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值