LeetCode Reorder List
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.
For example,Given {1,2,3,4}
, reorder it to {1,4,2,3}
.
在最开始的编程想法里,由于审题失误,看成以为是除了第一个元素以外,将剩余部分反转过来。所以在提交过程中长度大于3的是都不能通过的。后来才发现这个问题,重新思考。
在第一遍提交时,time limiting。由于在编码过程中的想法是顺序从链表开始,第一个就找到最后一个元素改变链表,知道指针为空时。那样每次都查找链表末尾。这样就要遍历链表n/2次。这样时间复杂度过高,不能通过。
之后,为了提高效率,减少遍历链表次数。那么首先,遍历一次链表,得到链表长度,这样将链表分为前部和后部两部分。第二次利用一开始写错的代码(偶尔看错题也是有好处的)讲后部的链表反转过来。这样就可以一个对一个改变链表结构了。
public class Solution {
public void reorderList(ListNode head) {
if(head ==null || head.next == null || head.next.next == null)return;
int length = size(head);
int half = length/2 + length%2;
ListNode pStart = head;
ListNode pStr = head;
ListNode p = head;
for(int i=1;i<half;i++)
{
pStr = pStr.next;
}
p = pStr;
pStr = pStr.next;
p.next = null;
pStr = reverse(pStr);
ListNode pEnd1 = pStart;
ListNode pEnd2 = pStr;
for(int i=0;i<length/2;i++)
{
pEnd1 = pEnd1.next;
pEnd2= pEnd2.next;
pStart.next = pStr;
pStr.next = pEnd1;
pStart = pEnd1;
pStr = pEnd2;
}
}
public ListNode reverse(ListNode head)
{
if(head == null || head.next == null)return head;
ListNode pStart = head;
ListNode insert = head.next;
ListNode pStr = insert;
pStart.next = null;
while(insert != null)
{
pStr = pStr.next;
insert.next = pStart;
pStart = insert;
insert = pStr;
}
return pStart;
}
public int size(ListNode head)
{
int length = 0;
if(head == null)return length;
ListNode start = head;
while(start != null)
{
length = length + 1;
start = start.next;
}
return length;
}
}