LeetCode | Partition List

100 篇文章 0 订阅
13 篇文章 0 订阅

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小的数据,并按照大小顺序依次排在最前面,而>=它的数据不需要变化
同样,写了一个比较残的,还CE
// 我写了一个head作为新的存储头节点,然后将所有的按照顺序拿到head里面
//哦我似乎看错题意了,不需要排序…

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if(head==NULL || head->next==NULL) return head;
        ListNode root(-1);
        root.next=head;

        ListNode* temp=&root;
        ListNode* head2=temp; 
        //需要遍历整个链表 
        while(temp->next!=NULL) {
            int flag=0;
            //从头部开始向后找,找到比x小的数据
            while(temp->next!=NULL) {
                //获取当前的值 
                int val=temp->next->val;
                if(val<x){
                    flag=1;break;
                }
                temp=temp->next;
            }
            if(flag){
                //当前temp的next的值是需要被提前的
                ListNode* node=temp->next;

                //需要将这个node按照从小到大的顺序,加入head组里面 
                ListNode* t=head2;
                while(t->next!=NULL){
                    if(t->next->val<node->val)
                    t=t->next;
                }
                //目前找到的是第一个比val大的数据的位置,它在t->next里
                //于是当前数据应当插入t和t->next之间
                node->next=t->next;
                t->next=node;

                //原链上这个值需要被跳过 
                temp->next=temp->next->next;
            }
        }
        //结束之后,需要将head2尾部连到root.next上
        ListNode* end=head2;
        while(end->next!=NULL) end=end->next;

        end->next=root.next;
        return head2;
    }
};

正解,还是双指针大法好啊

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        //利用双链表,直接将不同大小的数据分流到不同的数组中
        ListNode left(-1);
        ListNode right(-1);

        ListNode* left_cur=&left;
        ListNode* right_cur=&right;

        //ok好好看看链表使用for循环的方法
        for(ListNode* cur=head;cur!=NULL;cur=cur->next){
            if(cur->val<x){
                //从尾部添加
                left_cur->next=cur;
                left_cur=cur;
            }
            else{
                right_cur->next=cur;
                right_cur=cur;
            }
        }

        left_cur->next=right.next;
        right_cur->next=NULL;
        return left.next;
    }
};

于是重写了我的代码,发现一个巨大的缺陷,
就是如果尝试只使用一个head2,而从原数组中采取删除元素的方式
//当然是因为我处理的有点残
会导致head_cur的尾插变为insert操作

/**
 * 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 || head->next==NULL) return head;
        ListNode root(-1);
        ListNode head2(-1);
        root.next=head;

        ListNode* temp=&root;
        ListNode* head_cur=&head2;
        for(;temp!=NULL && temp->next!=NULL;temp=temp==NULL?NULL:temp->next){
            if(temp->next->val<x){
                head_cur->next=temp->next;
                head_cur=head_cur->next;

                //这种方法有个很大的问题在于
                //删除了某个元素之后,上述尾插的方法,有可能会变为insert
                //例如
                // Input:
                //     [1,2,3]
                //     4
                //     Output:
                //     [1,3,2]
                //     Expected:
                //     [1,2,3]
                //删除数组中的这个元素(跳过)
                //temp->next=head_cur==NULL?NULL:head_cur->next;
            }
        }

        //结束之后,需要将head2尾部连到root.next上
        head_cur->next=root.next;
        return head2.next;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值