重新排序链接列表

时间:2018-06-27 11:42:28

标签: java pointers merge linked-list reorderlist

给出一个单链表L:L0→L1→…→Ln-1→Ln, 将其重新排序为:L0→Ln→L1→Ln-1→L2→Ln-2→…

您不能修改列表节点中的值,只能更改节点本身。
我的解决方案是这样的。
我的想法是,我们首先找到中间元素,然后从中间的下一个元素到末尾反转列表,然后合并它们,但是我的问题是,如果它的主要功能是类似 public ListNode reorderList(ListNode ),那么我应该返回什么来获取完整列表。谢谢。

class Solution {
    public void reorderList(ListNode head) {
        if (head == null || head.next == null) {
            return;
        }

        ListNode mid = findMiddle(head);
        ListNode tail = reverse(mid.next);
        mid.next = null;
        merge(head, tail);
    }
       //to find the middle node of linked list
       private ListNode findMiddle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head.next;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
    //to reverse the nodes in linked list
    private ListNode reverse(ListNode head) {
       ListNode prev = null;
       ListNode curr = head;
       ListNode next = null;
        while(curr!=null){
            next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        head = prev;
        return head;
    }
    //to merge both the start and tail node.
    private void merge(ListNode headA, ListNode headB) {
        ListNode dummy = new ListNode(0);
        while (headA != null && headB != null) {
            dummy.next = headA;
            headA = headA.next;
            dummy = dummy.next;

            dummy.next = headB;
            headB = headB.next;
            dummy = dummy.next;
        }
        if (headA != null) {
            dummy.next = headA;
        } else if (headB != null) {
            dummy.next = headB;
        }
  } 
}

1 个答案:

答案 0 :(得分:1)

最好找到最后一个节点,将其删除,然后将其插入当前位置。这样可以节省计算和查找中间数的麻烦。

请参见下面的方法fold

static class MyList<T> {
    Node<T> head;

    class Node<T> {
        final T data;
        Node<T> next;

        Node(T data) {
            this.data = data;
        }
    }

    /**
     * Adds the data to the list.
     */
    public void add(T data) {
        Node<T> node = new Node<>(data);
        if ( head == null ) {
            head = node;
        } else {
            last().next = node;
        }
    }

    /**
     * Finds the node previous to the one specified
     */
    private Node<T> prev(Node<T> it) {
        // Singly linked so we must search.
        Node<T> node = head;
        Node<T> prev = null;
        while(node != it && node != null) {
            prev = node;
            node = node.next;
        }
        return node != null ? prev: null;
    }

    /**
     * Finds the last node.
     */
    private Node last() {
        Node<T> last = head;
        // Find the end.
        while(last.next != null) {
            last = last.next;
        }
        return last;
    }

    /**
     * Folds the list back on itself, interleaving as it goes.
     */
    public void fold() {
        Node<T> node = head;
        // For each node.
        while(node != null) {
            // Find last
            Node<T> last = last();
            // Remove it.
            Node<T> prev = prev(last);
            prev.next = null;
            // Insert it here.
            last.next = node.next;
            node.next = last;
            // Step past the added one.
            node = node.next;
            if(node != null) {
                node = node.next;
            }
        }
    }

    /**
     * String version of the list.
     */
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        Node<T> node = head;
        while(node != null) {
            sb.append(node.data).append(",");
            node = node.next;
        }
        // Remove the last comma.
        int comma = sb.lastIndexOf(",");
        if(comma >= 0) {
            sb.deleteCharAt(comma);
        }
        sb.append("]");
        return sb.toString();
    }
}

public void test() {
    MyList<Integer> list = new MyList<>();
    // Numbers 0 to 10.
    for(int i = 0; i < 10; i++) {
        list.add(i);
    }
    // Print it before folding.
    System.out.println(list);
    // Fold it.
    list.fold();
    // Print after folding.
    System.out.println(list);
}