LeetCode 143. 重排链表*

基本思想:

有两种主流思路: 1.直接递归,这里自己参照之间一题写的,比较简单,直接首尾两个指针,向中间靠拢;

2.等量中间拆分,将后半段逆序,然后逐个合并即可;

第二种可以涉及多个链表操作,注意一下;

具体代码:

递归:

/**
 * 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 fun(ListNode* &pre,ListNode* now,ListNode* &newhead,ListNode* hh,bool &flag) {
        if (now == NULL)
        return;
        fun(pre, now->next, newhead,hh,flag);
        if (flag) {
            if (pre == now) {
                flag = false;
                newhead->next = pre;
                pre->next = NULL;
                return;
            }
            newhead->next = pre;
            pre = pre->next;
            newhead = newhead->next;
            newhead->next = now;
            newhead = newhead->next;
            newhead->next = NULL;
            if (now == pre)
                flag = false;
        }
    }
    void reorderList(ListNode* head) {
        ListNode* h = new ListNode(-1);
        ListNode* f = h;
        if (!head)
            return;
        ListNode* fast = head;
        ListNode* slow = head;
        bool flag = true;
        fun(slow, fast, f,h,flag);
        head=h->next;
    }
};

拆分合并:

/**
 * 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 reverse_fun(ListNode* pre, ListNode* now, ListNode*& newhead) {
        if (now == NULL) {
            return;
        }
        reverse_fun(pre->next, now->next, newhead);
        if (!now->next) {
            newhead = now;
        }
        now->next = pre;
    }

    ListNode* reverse_list(ListNode* head) {
        if (!head||!head->next)
            return head;
        ListNode* pre = head;
        ListNode* newhead = NULL;
        ListNode* h = head;
        reverse_fun(pre, h->next, newhead);
        head->next = NULL;
        return newhead;
    }

    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode* head =new ListNode(-1);
        ListNode* ret = head;
        while (l1 && l2) {
            head->next = l1;
            l1 = l1->next;
            head = head->next;
            head->next = l2;
            l2 = l2->next;
            head = head->next;
        }
        if (l1)
            head->next = l1;
        if (l2)
            head->next = l2;
        return ret->next;
    }

    void reorderList(ListNode* head) {
        if (!head || !head->next)
            return;
        ListNode* fast = head;
        ListNode* slow = head;
        while (fast) {
            slow = slow->next;
            fast = fast->next;
            if (fast)
                fast = fast->next;
        }
        ListNode* p = head;
        while (p->next != slow) {
            p = p->next;
        }
        p->next = NULL;
        fast = reverse_list(slow);
        head = merge(head, fast);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值