[LeetCode] 143. Reorder List

1. 原题链接:https://leetcode.com/problems/reorder-list/

2. 解题思路

  1. 找到中间节点,从中间节点位置断开,得到两个链表
  2. 对链表的后半截部分进行翻转
  3. 将前半截和翻转后的后半截链表进行合并

3. 算法

  1. 通过slow、fast指针找到链表的中间位置
  2. 对后半截链表进行翻转操作(注意:后半截链表从ceil(n/2)+1位置开始,ceil表示向上取整,整个链表从1开始)
  3. 对两个链表进行合并,因为进行了向上取整,所以前半截链表的长度大于等于后半截链表

4. 实现

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
    void reorderList(ListNode* head) {
        if(head == NULL || head->next == NULL) return;
        //通过slow、fast指针找到链表的中间位置
        ListNode *slow = head, *fast = head;
        while(fast != NULL && fast->next != NULL && fast->next->next != NULL){
            slow = slow->next;
            fast = fast->next->next;
        }
        
        //对后半截链表进行翻转操作
        //注意:后半截链表从ceil(n/2)+1位置开始,ceil表示向上取整,整个链表从1开始
        ListNode *sub_head = slow->next;
        sub_head = reverseList(sub_head);
        
        //对两个链表进行合并,因为进行了向上取整,所以前半截链表的长度大于等于后半截链表
        slow->next = NULL;
        ListNode *new_head = head;
        while(sub_head != NULL){
            ListNode *sub_next = sub_head->next;
            ListNode *new_next = new_head->next;
            sub_head->next = new_head->next;
            new_head->next = sub_head;
            sub_head = sub_next;
            new_head = new_next;
        }
    }
    
private:
    ListNode* reverseList(ListNode* head){
        if(head == NULL || head->next == NULL) return head;
        
        ListNode *n = head->next;
        ListNode *new_head = reverseList(head->next);
        head->next = n->next;
        n->next = head;
        return new_head;
    }
};
posted @ 2020-02-19 15:35  wengle  阅读(151)  评论(0编辑  收藏  举报