Leetcode reorder-list

本文介绍了一种链表操作算法,该算法将链表分为两部分,反转后半部分并将其与前半部分合并,实现链表元素的交错排列。通过这种方法,可以在不额外占用空间的情况下重新组织链表。

https://leetcode.com/problems/reorder-list/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode* head) {
        if(head == nullptr or head->next == nullptr) return ;
        ListNode* slow=head,*fast=head,*prev;
        // 这个地方是 and
        while(fast and fast->next ){
            prev = slow;
            slow = slow->next;
            // cout<<slow->val<<endl;
            fast = fast->next->next;
        }
//         这个找中点的方法,均分或者 后面多一个。
        ListNode* slow2;

        prev->next = nullptr;
        
        ListNode* s = head;
        while(s){cout<<s->val<<endl;s=s->next;}
        
        slow2 = rev(slow);
        
        // ListNode* s = slow2;
        // while(s){cout<<s->val<<endl;s=s->next;}
        
        head = merge3(head,slow2);
        
        return ;
    }
    
    ListNode* rev(ListNode* h){
        ListNode* prev =nullptr,*cur = h,*nxt;
        if(cur == nullptr or nxt == nullptr) return h;
        while(cur != nullptr){
            // cout<<cur->val<<endl;
            nxt = cur->next;
            cur->next=prev;
            prev = cur;
            cur = nxt;
            // cur = cur->next;
            
        }
        // 这里不知道为什么不可以用赋值指针的形式来,head = prev。会出错。
        return prev ;
    }
    
//     void merge(ListNode* h,ListNode* e){
//         if(h == nullptr or e == nullptr) return ;
//         ListNode* cur = h;
//         // *havf = e,*nxt;
//         while(cur != nullptr){
//             // cout<<cur->val<<endl;
//             ListNode* nxt = cur->next;
//             ListNode* havf = e->next;
            
//             cur->next = e;
//             cout<<cur->val<<endl;
//             if(nxt = nullptr) break;
            
//             e->next = nxt;
//             // cout<<nxt->val<<endl;
//             cur = nxt;
//             e=havf;
// //             cur->next = havf;
// //             // if(cur == nullptr) break;
// //             havf = havf->next;
// //             cout<<havf->val<<endl;
// //             cur = cur->next;
// //             cur->next = nxt;
// //             cur=cur->next;
//         }
//         // if(havf != nullptr) cur->next = havf;
//         return ;
//     }
    
    ListNode* merge2(ListNode* l1,ListNode* l2){
        if(!l1) return l2 ;
        if(!l2) return l1 ;
        l1->next = merge2(l2,l1->next);
        return l1;
    }
    
    ListNode* merge3(ListNode* l1,ListNode* l2){
        ListNode *n1,*n2;
        ListNode* h = l1;
        while(l1){
            n1 = l1->next;
            n2 = l2->next;
            
            l1->next = l2;
            
            if(!n1) break;  // 靠这个中断来留住下面长的list的小尾巴。
            
            l2->next = n1;
            
            l1 = n1;
            l2 = n2;
        }
        
        return  h;
    }
    
    
};

主要思路是:把链表中间分开来,然后反转后面一半,在合并两个链表。

自己一开始是想把链表单独反转一份,然后,重新合成一个。这样有点浪费空间,需要思考空间的浪费程度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值