美文网首页
Reorder List

Reorder List

作者: ab409 | 来源:发表于2015-11-20 20:13 被阅读33次

    Reorder List


    今天是一道有关链表的题目,来自LeetCode,难度为Medium,Acceptance为23%

    题目如下

    Given a singly linked list L: L0→L1→…→Ln-1→Ln,
    reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
    You must do this in-place without altering the nodes' values.
    Example
    For example,
    Given 1->2->3->4->null, reorder it to 1->4->2->3->null.

    解题思路及代码见阅读原文

    回复0000查看更多题目

    解题思路

    首先,该题是要将链表末尾的节点反向合并到链表中。因为是单向链表,所以一定涉及到反转链表的操作,那么我第一个想到的就是用一个栈,先将所有的节点进栈,然后在合并的时候出栈即可。

    然而,用上述方法提交代码会得到Memory Limit Exceed的错误。那么显然用O(n)的方法是不行的,可以考虑就是采用O(1)的算法。

    那么,我们可以采用如下思路:一、将链表从中间分开,分成两个链表;二、将后面一个链表反转;三、合并两个链表。第三步合并链表相对比较简单,较为复杂的是前面两步。

    第一步分开链表,我们可以采用如Linked List Cycle(回复022查看)中采用的快慢指针的方法,当快指针到底链表末尾的时候,慢指针自然到达链表的中点,在此处即可将链表分开。

    第二步反转链表方法就有很多了,可以采用头插法,也可以采用每个节点依次指向前一个节点,这里我采用的第二种方法。

    下面我们来看代码。

    代码如下

    /**
     * Definition for ListNode.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int val) {
     *         this.val = val;
     *         this.next = null;
     *     }
     * }
     */ 
    public class Solution {
        /**
         * @param head: The head of linked list.
         * @return: void
         */
        public void reorderList(ListNode head) {  
            // write your code here
            if(null == head)
                return;
            // find mid node
            ListNode fast = head, slow = head;
            while(fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
            }
            ListNode head2 = slow.next;
            slow.next = null;
            
            //reverse
            head2 = reverse(head2);
            
            //merge
            merge(head, head2);
        }
        
        private ListNode reverse(ListNode head) {
            if(head == null)
                return null;
            ListNode current = head, next = current.next, prev = null;
            while(current != null) {
                current.next = prev;
                prev = current;
                current = next;
                if(current != null)
                    next = current.next;
                else
                    next = null;
            }
            return prev;
        }
        
        private ListNode merge(ListNode head1, ListNode head2) {
            if(null == head1)
                return head2;
            if(null == head2)
                return head1;
            ListNode p = head1, next1 = head1.next, next2 = head2.next;
            while(head1 != null && head2 != null) {
                head1.next = head2;
                head2.next = next1;
                head1 = next1;
                head2 = next2;
                if(head1 != null)
                    next1 = head1.next;
                if(head2 != null)
                    next2 = head2.next;
            }
            return p;
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:Reorder List

          本文链接:https://www.haomeiwen.com/subject/qrwlhttx.html