[leetCode]143. 重排链表
线性表
链表不能直接对下标进行访问,所以可以将链表的节点全部存入线性表中,然后就可以通过下标直接访问链表节点然后重建链表
class Solution {
public void reorderList(ListNode head) {
if (head == null) return;
List<ListNode> list = new ArrayList<>();
ListNode node = head;
while (node != null) {
list.add(node);
node = node.next;
}
int i = 0, j = list.size() - 1;
while (i < j) {
list.get(i).next = list.get(j);
i++;
list.get(j).next = list.get(i);
j--;
}
list.get(i).next = null;
}
}
寻找链表中间节点+链表逆序+合并链表
可以看到目标链表是原链表右半部分反转后和左半部分合并的结果,因此解决此题可以划分为三步:
- 找到链表的中间节点
- 将右半部分链表反转
- 合并左右两部分
class Solution {
public void reorderList(ListNode head) {
if (head == null) return;
ListNode mid = middleNode(head);
ListNode l1 = head;
ListNode l2 = mid.next;
mid.next = null;
l2 = reverseList(l2);
mergeList(l1, l2);
}
private ListNode middleNode(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
private ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
while (cur != null) {
ListNode tempNext = cur.next;
cur.next = prev;
prev = cur;
cur = tempNext;
}
return prev;
}
private void mergeList(ListNode l1, ListNode l2) {
while (l1 != null && l2 != null) {
ListNode tempL1Next = l1.next;
ListNode tempL2Next = l2.next;
l1.next = l2;
l1 = tempL1Next;
l2.next = l1;
l2 = tempL2Next;
}
}
}