题目:
原链表排列为: L: L0→L1→…→Ln-1→Ln,
改变排列为: L0→Ln→L1→Ln-1→L2→Ln-2→…
For example,
Given{1,2,3,4}, reorder it to{1,4,2,3}.
原地方法:
1.快慢指针找到中间节点;
2.对中间节点之后的链表进行反转;
3.对两个分链表进行合并。
public class Solution {
//主接口函数
public void reorderList(ListNode head) {
if(head == null||head.next == null)
return;
ListNode mid=fidMid(head);
ListNode first=head;
ListNode second=mid.next;
mid.next=null;
second=reverse(second);
head=combine(first,second);
}
//findMid链表通法
public ListNode fidMid(ListNode head)
{
ListNode first=head;
ListNode second=head;
while(second.next!=null&&second.next.next!=null)
{
second=second.next.next;
first=first.next;
}
return first;
}
//reverse链表通法
public ListNode reverse(ListNode head)
{
ListNode pre=head;
ListNode cur=head.next;
while(cur!=null)
{
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
head.next=null;
head=pre;
return head;
}
//合并链表
public ListNode combine(ListNode first,ListNode second)
{
ListNode head=first;
while(first!=null&&second!=null)
{
ListNode fnext=first.next;
ListNode snext=second.next;
second.next=fnext;
first.next=second;
first=fnext;
second=snext;
}
return head;
}
}
若用栈Stack来解决
将后半段链表按index从大到小的顺序插入原链表的相应位置,首先想到用一个stack辅助操作。
设置快慢指针找到中间节点(findMid找到中间节点或两个中间节点中的前一个);
代码如下:
public class Solution {
public void reorderList(ListNode head) {
if(head==null||head.next==null)
return;
Stack<ListNode> stack=new Stack();//用来将后半段结点反序输出;
ListNode mid=findMid(head);//当结点为奇数,返回中间节点,节点为偶数,返回两个中间节点中的前一个;
ListNode cur=mid.next;
while(cur!=null)
{
stack.push(cur);
cur=cur.next;
}
mid.next=null;
ListNode p1=head;
ListNode p2=p1.next;
while(!stack.empty())
{
ListNode temp=stack.pop();
p1.next=temp;
temp.next=p2;
if(p2!=null)
{
p1=p2;
p2=p2.next;
}
}
}
//findMid
public ListNode findMid(ListNode head)
{
ListNode prear=head;
ListNode pfront=head;
while(prear.next!=null&&prear.next.next!=null)
{
prear=prear.next.next;
pfront=pfront.next;
}
return pfront;
}
}