这一道题的思路其实就是把链表后半段,依次插入前半段中,且需要把后半段链表进行反转。
思路一:很容易想到的就是使用栈储存后半段来进行反转,然后再依次从栈取出进行合并。
代码如下:
public void reorderList(ListNode head) {
ListNode start = head;
ListNode end = head;
int count = 0;
while (end != null){
end = end.next;
count++;
}
if (count <= 2) return;
count = count/2+1;
end = head;
ListNode record = null;
while (count != 0){
count--;
if (count == 0) record = end;
end = end.next;
}
Deque<ListNode> deque = new LinkedList<>();
while (end != null){
deque.addLast(end);
end = end.next;
}
record.next = null;
while (!deque.isEmpty()){
ListNode node = deque.removeLast();
node.next = start.next;
start.next = node;
start = start.next.next;
}
该思路是很容易想到的,但是一般面对链表这种题目,都可以考虑原地算法。
思路二
- 使用快慢指针进行中点定位。
- 对后半段链表进行反转。
- 然后进行两两合并。
代码如下
public void reorderList1(ListNode head) {
if (head.next == null || head.next.next ==null) return;
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode pre = null;
ListNode cur = slow.next;
slow.next = null;
ListNode next;
while (cur != null){
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
slow = head;
cur = pre;
while (cur != null){
next = cur.next;
cur.next = slow.next;
slow.next = cur;
slow = slow.next.next;
cur = next;
}
基本上就为这道题的最优解,空间复杂度为O(1)。