重排链表

来源:互联网 发布:ubuntu查找文件命令 编辑:程序博客网 时间:2024/06/08 08:41

题目:给定一个单链表L: L0→L1→…→Ln-1→Ln, 重新排列后为:L0→Ln→L1→Ln-1→L2→Ln-2→…, 必须在不改变节点值的情况下进行原地操作
例子:给出链表1->2->3->4->null,重新排列后为1->4->2->3->null。

步骤:

  1. 把整个链表划分成2个等长的子链表,如果原链表长度为奇数,那么第一个子链表的长度多1。
  2. 翻转第二个子链表。
  3. 将两个子链表合并。
public class Solution {    private ListNode reverse(ListNode head) {        ListNode newHead = null;        while (head != null) {            ListNode temp = head.next;            head.next = newHead;            newHead = head;            head = temp;        }        return newHead;    }    private void merge(ListNode head1, ListNode head2) {        int index = 0;        ListNode dummy = new ListNode(0);        while (head1 != null && head2 != null) {            if (index % 2 == 0) {                dummy.next = head1;                head1 = head1.next;            } else {                dummy.next = head2;                head2 = head2.next;            }            dummy = dummy.next;            index ++;        }        if (head1 != null) {            dummy.next = head1;        } else {            dummy.next = head2;        }    }    private ListNode findMiddle(ListNode head) {        ListNode slow = head, fast = head.next;        while (fast != null && fast.next != null) {            fast = fast.next.next;            slow = slow.next;        }        return slow;    }    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);    }}
0 0
原创粉丝点击