【算法】【线性表】【链表】Reorder List 重排链表
1 题目
You are given the head of a singly linked-list. The list can be represented as:
L0 → L1 → … → Ln - 1 → Ln
Reorder the list to be on the following form:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list's nodes. Only nodes themselves may be changed.
Example 1:
Input: head = [1,2,3,4]
Output: [1,4,2,3]
Example 2:
Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]
Constraints:
- The number of nodes in the list is in the range
[1, 5 * 104]
. 1 <= Node.val <= 1000
2 解答
大致思路就是:先利用快慢指针找中间位置,然后将右边的链表反转,然后再左右遍历两个链表,将右边的挨个插入到左边的链表即可:
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ class Solution { public void reorderList(ListNode head) { // 参数边界校验 节点为空 1个节点 2个节点 都可以直接返回 if (head == null || head.next == null || head.next.next == null) { return; } // 先找到中间位置 // 分别遍历两边链表 // 将右边的节点依次插入左边的缝隙 (因为是单向链表,所以右边的链表先反转一下再遍历) // 1 2 3 4 5 // 1 2 3 4 // 快慢指针 寻找中间位置 slowNode 到达中间位置 ListNode quickNode = head; ListNode slowNode = head; while (quickNode != null && quickNode.next != null) { quickNode = quickNode.next.next; // 说明下次循环要结束了 需要把当前的 slowNode 的 next 设置为空 if (quickNode == null || quickNode.next == null) { ListNode temp = slowNode.next; slowNode.next = null; slowNode = temp; } else { slowNode = slowNode.next; } } // 对 slowNode 开始的节点进行反转 // 还是老办法 加个头节点方便反转 ListNode slowPreNode = new ListNode(0); slowPreNode.next = slowNode; ListNode node = slowNode; while (node != null) { ListNode nextNode= node.next; if (nextNode != null) { node.next = nextNode.next; nextNode.next = slowPreNode.next; slowPreNode.next = nextNode; continue; } node = node.next; } // 一个从 head 开始 一个从 slowPreNode.next 开始 ListNode leftNode = head; ListNode rightNode = slowPreNode.next; // 左边的链表长度小于右边的 所以只要判断左边的链表不为空即可 while (leftNode != null) { ListNode nextNode = leftNode.next; if (nextNode == null) { // 左边到了最后一个节点了,直接把右边的赋值(右边没遍历完的)给左边的next即可 leftNode.next = rightNode; break; } else { // 右边的节点保留下 node = rightNode; // 右边后移 rightNode = rightNode.next; // 将 node 插入进来 node.next = leftNode.next; leftNode.next = node; leftNode = node.next; } } } }
加油。