问题描述:
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}
.
原问题链接:https://leetcode.com/problems/reorder-list/
问题分析
在写具体的代码实现之前,我们先看问题的要求。它要求是将如L0, L1, L2...Ln的链表变成L0, Ln, L1, Ln-1...。这种样式相当于将链表从正中间拆分成两截。对于后面的那一截先反转一下。然后再将这两截链表按照顺序依次的加入元素,构成一个新的链表。
只要找到这个规律,后面的实现就有思路了。我们首先找到链表中间节点,因为要从它开始划分成两截。从实现的角度来说,我们可以用快慢指针的方式。当快指针到达链表末尾的时候,慢指针所在的位置就是分割点。在得到这个分割点之后,我们再将后面的这部分反转。关于反转的具体实现可以参考之前的讨论。
在反转完成之后,剩下的就是要考虑怎么实现两个链表的合并了。因为这里是轮流加入元素合并。我们的详细实现可以参照如下图的流程:
一开始,我们有两个链表first, second,我们额外声明一个变量next:
在下一步的时候,我们实现元素的交叠:
它的作用相当于实现second.next = first.next; first.next = second; 然后我们再确定下一步first, second的位置:
这种调整相当于如下的代码:first = second.next; second = next; 这样,我们就完成了一个元素交叠的过程。我们通过循环上述的过程就可以实现最终的交叠。
结合上述的讨论,详细的代码实现如下:
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public void reorderList(ListNode head) { if(head == null || head.next == null) return; ListNode fast = head; ListNode slow = head; while(fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } ListNode first = head; ListNode half = slow.next; slow.next = null; half = reverse(half); while(first != null && half != null) { ListNode next = half.next; half.next = first.next; first.next = half; first = half.next; half = next; } } private ListNode reverse(ListNode node) { ListNode tmp = null, pre = null; while(node != null) { tmp = node; node = node.next; tmp.next = pre; pre = tmp; } return tmp; } }
相关推荐
leetcode中325题python leetcode 以 参考 和 Hash相关 1_两数之和 387_字符串中的第一个唯一字符 链表操作 ...reorder-list 148 排序链表 sort-list 234 回文链表 palindrome-linked-list 双指针遍历/滑动
LeetCodeLeetCode solutions(Java)树Minimum Depth of Binary Tree栈evaluate-reverse-polish-notation穷举max-points-on-a-line链表sort-list排序insertion-sort-list树binary-tree-postorder-traversal树binary-...
python python_leetcode题解之143_Reorder_List
javascript js_leetcode题解之143-reorder-list.js
* [Linked List](https://github.com/kamyu104/LeetCode#linked-list) * [Stack](https://github.com/kamyu104/LeetCode#stack) * [Queue](https://github.com/kamyu104/LeetCode#queue) * [Heap]...
- **Reorder List**:按照特定规则重新排列链表。 - **Partition List**:将链表按值分割成两个部分。 - **Add Two Numbers**:两个非负整数相加,结果存储在链表中。 - **Copy List with Random Pointer**:...
def reorderList(self, head: ListNode) -> None: if not head or not head.next: return # 找到链表中点 mid = self.findMid(head) # 反转后半部分链表 l2 = mid.next mid.next = None l2 = self....
def reorderList(head): if not head or not head.next: return head mid = find_mid(head) next_to_mid = mid.next mid.next = None right = reverse_list(next_to_mid) left = head right_tail = None ...
- **重排链表(Reorder List)**: 给定一个单链表L,将其重新排列为A-B-A-B形式。 - **划分链表(Partition List)**: 将链表中所有小于x的节点移到所有大于或等于x的节点之前。 - **两数相加(Add Two Numbers)**: 给定...
public ListNode reorderList(ListNode head) { if (head == null || head.next == null) return head; // 分离奇数和偶数链表 ListNode odd = head, even = head.next, evenHead = even; while (even != null...
在提供的 `Solution` 类中,`reorderList` 函数实现了以上步骤。首先检查链表是否为空,然后执行上述三个步骤。这个函数的时间复杂度是 O(n),因为我们需要遍历链表两次,一次找到中间节点,一次进行合并;空间...
3. **143.py** - 可能对应的是LeetCode的143题,"Reorder List"(重排链表),涉及链表操作和双指针技巧。 4. **140.py** - 可能是LeetCode的140题,"Word Break II"(单词拆分II),这是一道动态规划问题,需要...
1. **Reorder List** (重新排序链表): 这个问题涉及到链表的操作,包括遍历链表、找到中间节点以及翻转链表的部分子集。在Java中,链表通常用`LinkedList`类来实现,解决问题的关键在于理解和操作链表节点的指针。 ...