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}.
给定一个链表让我们重新排列它,例如以前的顺序为0-1-2-3-4,排列后的顺序为0-4-1-3-2。我们首先要找到中间的节点,用快慢指针,这个比较简单,不过值得注意的是节点是奇数和偶数的不同情况。找到中间节点后我们可以借助堆栈将后半部分的节点压栈,然后从头结点开始一个一个的处理,可以解决。堆栈实际上帮我们将链表的后半段反转了,如果我们不借助堆栈也可以解决,我们可以将链表从中间节点分为两段,将后半段反转,然后再将两个链表合为一个链表,这样就不需要借助堆栈,时间复杂度为O(n), 空间复杂度为O(1)。下面是两种方法的代码:
1,Using stack
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public void reorderList(ListNode head) { Stackstack = new Stack (); if(head == null) return; ListNode fast = head; ListNode slow = head; while(fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; } if(fast != null){ slow = slow.next; } while(slow != null) { stack.push(slow); slow = slow.next; } while(!stack.isEmpty()){ ListNode top = stack.pop(); ListNode temp = head.next; head.next = top; top.next = temp; head = temp; } head.next = null; } }
2,Without stack
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public void reorderList(ListNode head) { if(head == null || head.next == null) return; ListNode fast = head; ListNode slow = head; ListNode pre = null; //get the middle node, and cut list into two sublists while(fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } ListNode midNode = slow.next; slow.next = null; // reverse the latter part ListNode newNode = reverseLatterPart(midNode); //merge two sublists while(newNode != null) { ListNode tem = head.next; head.next = newNode; head = newNode; newNode = tem; } } private ListNode reverseLatterPart(ListNode head) { ListNode prev = null; ListNode tem = null; while(head != null) { tem = head.next; head.next = prev; prev = head; head = tem; } return prev; } }