Tuesday, March 10, 2020

Reorder List

Given a singly linked list LL0L1→…→Ln-1Ln,
reorder it to: L0LnL1Ln-1L2Ln-2→…
You may not modify the values in the list's nodes, only nodes itself may be changed.
Example 1:
Given 1->2->3->4, reorder it to 1->4->2->3.
Example 2:
Given 1->2->3->4->5, reorder it to 1->5->2->4->3.
/**
 * 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) {
        stack<ListNode*> st;
        if (head == NULL || head -> next == NULL || head -> next -> next == NULL) {
            return;
        }
        
        int len = getLength(head);
        
        ListNode *trav = head;
        int mid = (len % 2 == 1 ? len/2 : (len/2) - 1);
        for (int i = 0; i < len; i++) {
            ListNode *tmp = trav;
            trav = trav -> next;
            if (i > mid) {
                tmp -> next = NULL;
                st.push(tmp);
            }
        }
        
        // Merge.
        handle(head, st);
    }
    
    int getLength(ListNode *head) {
        int ans = 0;
        while (head != NULL) {
            ans++;
            head = head -> next;
        }
        return ans;
    }
    
    void handle(ListNode *head, stack<ListNode*>& st) {
        ListNode *trav = head;
        while (!st.empty()) {
            ListNode *last = st.top(); st.pop();
            ListNode *tmp = trav -> next;
            if (tmp == last) {
                return;
            }
            trav -> next = last;
            trav = trav -> next;
            trav -> next = tmp;
            trav = trav -> next;
        }
        trav -> next = NULL;
        
    }
};

===========
class Solution {
public:
    void reorderList(ListNode *head) {
        if (!head || !head->next || !head->next->next) return;
        stack<ListNode*> st;
        ListNode *cur = head;
        while (cur) {
            st.push(cur);
            cur = cur->next;
        }
        int cnt = ((int)st.size() - 1) / 2;
        cur = head;
        while (cnt-- > 0) {
            auto t = st.top(); st.pop();
            ListNode *next = cur->next;
            cur->next = t;
            t->next = next;
            cur = next;
        }
        st.top()->next = NULL;
    }
};

==========
/**
 * 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 == NULL || head -> next == NULL) {
            return;
        }
        // find the other half.
        ListNode *other_half = extractOtherHalf(head);
        
        // reverse the other half.
        other_half = reverse(other_half);
        
        // merge with the other half.
        merge(head, other_half);
    }
    
    ListNode *extractOtherHalf(ListNode *head) {
        ListNode *slow = head, *fast = head;
        ListNode *pre = NULL;
        while (fast != NULL && fast -> next != NULL) {
            pre = slow;
            slow = slow -> next;
            fast = fast -> next -> next;
        }
        pre -> next = NULL;
        return slow;
    }
    
    ListNode *reverse(ListNode *head) {
        ListNode *cur = head, *pre = NULL, *next = NULL;
        while (cur != NULL) {
            next = cur -> next;
            cur -> next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
    
    void merge(ListNode *head, ListNode *head2) {
        ListNode *last = NULL;
        while (head != NULL && head2 != NULL) {
            ListNode *head_next = head -> next;
            ListNode *head2_next = head2 -> next;
            head -> next = head2;
            head2 -> next = head_next;
            head = head_next;
            last = head2;
            head2 = head2_next;
        }
        
        if (head2 != NULL) {
            last -> next = head2;
        }
    }
    
};

No comments:

Post a Comment