1.問題
Given a singly linked list L: (L0 , L1 , L2...Ln-1 , Ln). Write a program to reorder it so that it becomes(L0 , Ln , L1 , Ln-1 , L2 , Ln-2...).struct Node
{
int val_;
Node* next;
};
Notes:
1)Space Complexity should be O(1)
2)Only the ".next" field of a node is modifiable.
該題目和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}.
2.分析
如果採用空間複雜度爲O(n)和時間複雜度爲O(1)的方法解決Reorder List問題,主要分爲以下三步:1)將單鏈表分爲前後兩個鏈表;
2)逆序分開後的第二個鏈表;
3)再將前後鏈表合併成一個單鏈表。
3.程序實現
/*
*@題目描述: 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}.
*@問題分析:1.將鏈表分成兩部分;
* 2.將第二個鏈表逆轉;
* 3.將兩個鏈表合併。
*/
//鏈表的數據結構
class ListNode{
ListNode next;
int val;
public ListNode(int val) {
// TODO Auto-generated constructor stub
this.val=val;
next=null;
}
}
public class ReorderList {
public static ListNode reverseList(ListNode head){
if(head==null || head.next==null)
return head;
ListNode preNode=head;
ListNode currNode=head.next;
while(currNode!=null){
ListNode tempNode=currNode.next;
currNode.next=preNode;
preNode=currNode;
currNode=tempNode;
}
head.next=null;
return preNode;
}
public static void reorderList(ListNode head){
if(head!=null && head.next!=null){
//將兩個鏈表從中間分爲兩個鏈表
ListNode slowNode=head;
ListNode fastNode=head;
while(fastNode!=null&&fastNode.next!=null&&fastNode.next.next!=null){
slowNode=slowNode.next;
fastNode=fastNode.next.next;
}
ListNode secondListHead=slowNode.next;
slowNode.next=null;
//逆轉第二個鏈表
secondListHead=reverseList(secondListHead);
ListNode pHead1=head;
ListNode pHead2=secondListHead;
//合併兩個分開的鏈表
while(pHead2!=null){
ListNode pTempNode1=pHead1.next;
ListNode pTempNode2=pHead2.next;
pHead1.next=pHead2;
pHead2.next=pTempNode1;
pHead1=pTempNode1;
pHead2=pTempNode2;
}
}
}
public static void printListInfo(ListNode head){
System.out.println("*****開始分隔符*****");
while(head!=null){
System.out.print(head.val);
head=head.next;
}
System.out.println("\n*****結束分隔符*****");
}
public static void main(String args[]){
ListNode listHead=new ListNode(3);
ListNode listNode1=new ListNode(4);
ListNode listNode2=new ListNode(5);
ListNode listNode3=new ListNode(6);
ListNode listNode4=new ListNode(7);
listHead.next=listNode1;
listNode1.next=listNode2;
listNode2.next=listNode3;
listNode3.next=listNode4;
System.out.println("Before Reorder list: ");
printListInfo(listHead);
reorderList(listHead);
System.out.println("after Reorder List:");
printListInfo(listHead);
}
}
*****開始分隔符*****
34567
*****結束分隔符*****
after Reorder List:
*****開始分隔符*****
37465
*****結束分隔符*****