Leet Code 143:Reorder List 对一个链表重新排序

来源:互联网 发布:java线程池原理 编辑:程序博客网 时间:2024/06/05 10:04
问题:Given a singly linked list LL0L1→…→Ln-1Ln,

reorder it to: L0LnL1Ln-1L2Ln-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}.

题解:对于一个链表L,L0L1→…→Ln-1Ln,对它进行重新排序,重新排序后的结果为L0LnL1Ln-1L2Ln-2→…,即最后一个插在第一个后面,倒数第二个插在第二个后面,倒数第三个插在第三个后面,。。。。     注意题目有个要求,你不能通过替换链表节点值的方式解决此问题

分析:我想有些人对这个问题应该比较熟悉,对于一个链表L,L0L1→…→Ln-1Ln,对它进行重新排序,排序后的结果

L0L(n/2+1)L1L(n/2+2)L2L(n/2+3)→…,即链表分为两部分,左边的长度-右边的长度<=1(链表长度偶数时,左右相等,奇数时左边多一个节

点)。右边第一个插在左边第一个后面,右边第二个插在左边第二个后面,右边第三个,插在左边第三个后面。。。

For example,

Given{1,2,3,4},reorder it to{1,3,2,4}

显然,解决这个问题分为两步

第一步,找到链表的中间位置

第二步,将右半部分插入左半部分

但是这个LeetCode问题中,对右半部分的插入顺序刚好与上述问题的插入顺序逆序,我们很自然的可以想到,在执行插入操作之前,应该有一个逆序操作,所以解决这个问题就分为了三步。

第一步,找到链表的中间位置

第二步,将右半部份做逆序调整

第三部,将右半部份插入到左半部分

以下是代码:

public void reorderList(ListNode head) {            if(head==null||head.next==null) return;                        //第一步,找到链表中间位置            ListNode p1=head;            ListNode p2=head;            while(p2.next!=null&&p2.next.next!=null){                 p1=p1.next;                p2=p2.next.next;            }                        //对右半部份执行逆序操作  1->2->3->4->5->6 to 1->2->3->6->5->4            ListNode preMiddle=p1;            ListNode preCurrent=p1.next;            while(preCurrent.next!=null){                ListNode current=preCurrent.next;                preCurrent.next=current.next;                current.next=preMiddle.next;                preMiddle.next=current;            }                        //将右半部份插入到左半部分  1->2->3->6->5->4 to 1->6->2->5->3->4            p1=head;            p2=preMiddle.next;            while(p1!=preMiddle){                preMiddle.next=p2.next;                p2.next=p1.next;                p1.next=p2;                p1=p2.next;                p2=preMiddle.next;            }        }

对三步中所涉及的指针操作的解析


0 0
原创粉丝点击