2019考研408的一道算法题,很伤心,在这里把算法思路理一下,别的不多说,向前看。找出中间结点,然后将后半部分结点逆序,最后将前半部分和后半部分连接起来。第一次统计结点个数n,第二次遍历,遍历到中间结点时,处理奇数个数和偶数个数的情况,若是奇数个数,最中间的节点将是变换结果后的最后一个结点,将其标记下来。注意在遍历时要保持链表不断裂。时间复杂度O(n),空间复杂度O(1)。
参考代码:
//leetcode 143. Reorder List
public static void reorderList(ListNode head) {
if(head==null||head.next==null||head.next.next==null)
return;
int n=0;
ListNode p = head;
while(p!=null){
++n;
p = p.next;
}
int mid = n/2,t=0;
p = head;
while(p!=null&&t<mid-1){
p = p.next;
++t;
}
ListNode end = null;
if(n%2==1){
end = p.next;
p = end.next;
end.next = null;
}else{
p = p.next;
}
ListNode vmNode = new ListNode(0);
while(p!=null){
ListNode next = p.next;
p.next = vmNode.next;
vmNode.next = p;
p = next;
}
vmNode = vmNode.next;
ListNode head_now = new ListNode(0);
p=head_now;
while(mid!=0){
--mid;
ListNode a1 = head.next,a2=vmNode.next;//保存下一个结点,以防断链,在这个地方调试了好久才发现
p.next = head;
p = p.next;
p.next = vmNode;
p = p.next;
head = a1;
vmNode = a2;
}
p.next = end;
head = head_now.next;
}