Reorder List @LeetCode

思路就是:

1 用快慢指针找到中间节点

2 翻转中间节点后一个元素到最后一个元素区间的所有元素

3 断开前半段和翻转后的后半段元素

4 把前半段和翻转后的后半段元素以交叉的方式合并起来

5 特殊处理输入为空,只有一个元素和只有两个元素的corner case,就是多加几个if...return


感想:可以看出翻转链表实在是非常重要,是做很多题目的基础。还有merge的思想也很重要!


package Level4;

import Utility.ListNode;

/**
 *
 * 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}.
 *
 */
public class S143 {

	public static void main(String[] args) {
		int[] list = {1};
		ListNode head = ListNode.create(list);
		reorderList(head);
	}

	public static void reorderList(ListNode head) {
		ListNode fast = head;
		ListNode slow = head;
		// 找到中间节点
		while(fast!=null && fast.next!=null){
			fast = fast.next.next;
			slow = slow.next;
		}
		
//System.out.println(slow.val);
		ListNode preReverse = slow;	// preReverse不用翻转,因为它永远在最后一个
		if(preReverse == null){
			return;
		}
		
		// 翻转后半段
		ListNode reHead = preReverse.next;
		if(reHead == null){
			return;
		}
		ListNode preCur = reHead.next;
		ListNode cur = reHead.next;
		reHead.next = null;
		while(cur != null){
			cur = cur.next;
			preCur.next = reHead;
			reHead = preCur;
			preCur = cur;
		}
		preReverse.next = reHead;
//head.print();
		
		// 交叉合并两个链表
		preReverse.next = null;		// 断开前半段和翻转后的后半段元素
		cur = head;
		while(reHead != null && cur!=null){
			ListNode tmp = cur.next;
			cur.next = reHead;
			reHead = reHead.next;
			cur.next.next = tmp;
			cur = tmp;
			tmp = cur.next;
		}
//head.print();
	}

}


原文地址:https://www.cnblogs.com/fuhaots2009/p/3478673.html