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}
.
Solution1:用stack解题
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public void reorderList(ListNode head) { if(head==null || head.next ==null ||head.next.next==null) return; ListNode current = head; Stack<ListNode> tails = new Stack<ListNode>(); int length =0; while(current!=null){ tails.push(current); current=current.next; length++; } current = head; for(int position=0; position<length-2; position+=2){ ListNode tail = tails.pop(); tail.next = current.next; current.next = tail; current = current.next.next; } if(length%2!=0) current.next=null; else current.next.next=null; return; } }
Solution2:第一步,找到list的中点(用两个步长为1和2的指针实现);第二步,讲list后半部分翻转;第三步,讲list前后部分合并。这种方法不用记录长度为奇数或偶数。
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public void reorderList(ListNode head) { if(head==null || head.next ==null ||head.next.next==null) return; ListNode tail=head, mid=head; while(tail.next!=null && tail.next.next!=null){ tail=tail.next.next; mid=mid.next; } //reverse the nodes after mid, produce 2 lists, first half list and second half list tail = mid.next; //the tail of second half list is tail mid.next = null; //first list from head to mid ListNode prev=null, next; while(tail!=null){//reverse list next = tail.next; tail.next = prev; prev = tail; if(next!=null) tail=next; else break; } //now tail is the head for the second half //merge two lists while(tail!=null){//use tail!=null because list started from tail is always shorter than list started from head next = tail.next; tail.next = head.next; head.next = tail; tail= next; head = head.next.next; } return; } }
注意翻转list的操作里当next==null时表示遍历到原list尾,即翻转list的头部,则不执行tail=next操作,否则tail会指向null,丢失翻转list的头部。
两种方法执行前都要判断head或head.next或head.next.next是否为null,因为此方法要求list中至少有三个元素,否则可直接返回。
时间: 2024-11-06 18:37:29