[leetcode] Reorder List

Given a singly linked list LL0→L1→…→Ln-1→Ln,

reorder it to: L0→LnL1→Ln-1→L2→Ln-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}.

https://oj.leetcode.com/problems/reorder-list/

思路:分三步走

  1.   从中间把链表分开(双指针法)
  2.   把后面的链表反序
  3.   合并两个链表
public class Solution {
    public void reorderList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null)
            return;

        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null && fast.next.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode second = slow.next;
        slow.next = null;
        second = reverse(second);
        merge(head, second);
    }

    private ListNode reverse(ListNode head) {
        if (head == null || head.next == null)
            return head;
        ListNode pre = head;
        ListNode cur = head.next;
        while (cur != null) {
            ListNode post = cur.next;
            cur.next = pre;
            pre = cur;
            cur = post;
        }
        head.next = null;
        return pre;
    }

    private void merge(ListNode first, ListNode second) {
        ListNode cur1 = first;
        ListNode cur2 = second;

        while (cur2 != null) {
            ListNode post1 = cur1.next;
            ListNode post2 = cur2.next;
            cur1.next = cur2;
            cur2.next = post1;
            cur1 = post1;
            cur2 = post2;

        }

    }

    public static void main(String[] args) {
        ListNode head = makeList(new int[] { 1 });
        printList(head);
        new Solution().reorderList(head);
        printList(head);
    }

    private static ListNode makeList(int[] a) {
        ListNode head = new ListNode(-1);
        ListNode p = head;
        for (int i = 0; i < a.length; i++) {
            p.next = new ListNode(a[i]);
            p = p.next;
        }
        return head.next;

    }

    private static void printList(ListNode head) {
        ListNode p = head;
        while (p != null) {
            System.out.print(p.val);
            if (p.next != null)
                System.out.print("->");
            p = p.next;
        }
        System.out.println();
    }
}

第二遍记录:

reverse 再练习下,画图分析下,开始写错了。

   private ListNode reverse(ListNode head) {
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode pre = head;
        ListNode cur = head.next;
        while(cur!=null){
            ListNode post=cur.next;
            pre.next=post;
            cur.next=dummyHead.next;
            dummyHead.next=cur;
            cur=post;
        }
        
        return dummyHead.next;
    }

第三遍记录:思路不变,注意细节。

  reverse的时候 最后head.next要至为null

  merge也比较简单,犯了个低级失误,指针变换的时候要赋值出去的指针记得要先复制出去,否则自己被改变了,再赋值出去就不对了,说的有点乱,总之注意变换的顺序。  

public class Solution {

    public void reorderList(ListNode head) {
        if (head == null || head.next == null || head.next.next == null)
            return;
        ListNode slow = head;
        ListNode fast = head;

        while (fast != null && fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        ListNode first = head;
        ListNode second = slow.next;
        slow.next = null;

        ListNode revSec = reverse(second);

        merge(first, revSec);
    }

    private ListNode merge(ListNode l1, ListNode l2) {
        ListNode head = l1;

        while (l1 != null && l2 != null) {
            ListNode l1Next = l1.next;
            ListNode l2Next = l2.next;

            l2.next = l1.next;
            l1.next = l2;

            l1 = l1Next;
            l2 = l2Next;
        }

        return head;
    }

    private ListNode reverse(ListNode head) {
        if (head == null || head.next == null)
            return head;

        ListNode newHead = new ListNode(-1);
        newHead.next = head;
        ListNode cur = head.next;

        while (cur != null) {
            ListNode post = cur.next;
            cur.next = newHead.next;
            newHead.next = cur;

            cur = post;
        }
        head.next = null;

        return newHead.next;

    }

    public static void main(String[] args) {
        ListNode head = ListUtils.makeList(1, 2, 3, 4, 5);
        ListUtils.printList(head);
        new Solution().reorderList(head);
        ListUtils.printList(head);
    }
}

参考:

http://www.programcreek.com/2013/12/in-place-reorder-a-singly-linked-list-in-java/

http://codeganker.blogspot.com/2014/03/reorder-list-leetcode.html

原文地址:https://www.cnblogs.com/jdflyfly/p/3829528.html