1. 程式人生 > >reorder-list

reorder-list


title: reorder-list
date: 2018-12-04 10:40:55
categories: LeetCode
tags: [List]


題目描述:

Given a singly linked list L: L 0→L 1→…→L n-1→L n,
reorder it to: L 0→L nL 1→L n-1→L 2→L n-2→…

You must do this in-place without altering the nodes’ values.

For example,
Given{1,2,3,4}, reorder it to{1,4,2,3}.

思路一:

這是一個單鏈表,按照題目描述,我們沒法從後往前找連結串列元素,為了實現這個目的,我們可以設定一個stack,這樣就可以記錄從後往前的資訊了。

程式碼:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode *
head) { if(!head || !head->next) return; ListNode* dummy = new ListNode(0); ListNode* rear = head; stack<ListNode*> st; while(rear) { st.push(rear); rear = rear->next; } rear =
st.top(); st.pop(); ListNode* headnext = head->next; ListNode* p = dummy; while(head->next != rear && head != rear) { headnext = head->next; head->next = rear; rear->next = NULL; p->next = head; p = p->next->next; head = headnext; rear = st.top(); st.pop(); } if(head == rear) { rear->next = NULL; p->next = rear; } if(head->next == rear) { head->next = rear; rear->next = NULL; p->next = head; } head = dummy->next; } };

思路二:

找到連結串列中間節點,將連結串列分為連結串列一,連結串列二;採用頭插法逆序連結串列二;合併連結串列一連結串列二。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void reorderList(ListNode *head) {
        
        //連結串列為空或者只有一個元素,不需要進行操作
        //(其實只有倆元素也不需要操作,可以合併到下邊情況)
        if(!head || !head->next)
            return;
        
        //找到中間節點,拆分連結串列為連結串列一,連結串列二
        ListNode* slow = head;
        ListNode* fast = head;
        ListNode* preslow;
        while(fast && fast->next)
        {
            preslow = slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        preslow->next = NULL;
        
        //採用頭插法,將連結串列二逆序
        ListNode* dummy = new ListNode(0);
        while(slow)
        {
            ListNode* slownext = slow->next;
            slow->next = dummy->next;
            dummy->next = slow;
            slow = slownext;
        }
        
        //將連結串列一連結串列二合併
        ListNode* firstList = head;
        ListNode* secondList = dummy->next;
        ListNode* firstListnext;
        ListNode* secondListnext;
        
        ListNode* p = dummy;
        while(firstList && secondList)
        {
            firstListnext = firstList->next;
            secondListnext = secondList->next;
            
            firstList->next = NULL;
            secondList->next = NULL;
            
            firstList->next = secondList;
            p->next = firstList;
            
            p = p->next->next;
            firstList = firstListnext;
            secondList = secondListnext;
        }
        
        //這段if可以不要
        //因為按照我們劃分,連結串列二元素個數總是大於等於連結串列一元素個數
        if(firstList)
        {
            firstList->next = NULL;
            p->next = firstList;
        }
        if(secondList)
        {
            secondList->next = NULL;
            p->next = secondList;
        }
        
        head = dummy->next;
    }
};