奇偶链表
难度:
标签:
题目描述
给定单链表的头节点 head
,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。
你必须在 O(1)
的额外空间复杂度和 O(n)
的时间复杂度下解决这个问题。
示例 1:
输入: head = [1,2,3,4,5] 输出: [1,3,5,2,4]
示例 2:
输入: head = [2,1,3,5,6,4,7] 输出: [2,3,6,7,1,5,4]
提示:
n ==
链表中的节点数0 <= n <= 104
-106 <= Node.val <= 106
代码结果
运行时间: 56 ms, 内存: 16.9 MB
/*
* 思路:
* 1. 由于Java Stream不适用于直接操作链表结构,我们可以将链表转换为列表,然后使用stream操作。
* 2. 创建两个列表分别存储奇数索引和偶数索引的节点。
* 3. 遍历原始链表,将节点按索引加入对应的列表。
* 4. 合并奇数和偶数列表。
* 5. 将合并后的列表转换回链表。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class Solution {
public ListNode oddEvenList(ListNode head) {
if (head == null) return null;
List<ListNode> nodes = new ArrayList<>();
while (head != null) {
nodes.add(head);
head = head.next;
}
List<ListNode> oddNodes = nodes.stream()
.filter(node -> nodes.indexOf(node) % 2 == 0)
.collect(Collectors.toList());
List<ListNode> evenNodes = nodes.stream()
.filter(node -> nodes.indexOf(node) % 2 != 0)
.collect(Collectors.toList());
List<ListNode> resultNodes = new ArrayList<>();
resultNodes.addAll(oddNodes);
resultNodes.addAll(evenNodes);
for (int i = 0; i < resultNodes.size() - 1; i++) {
resultNodes.get(i).next = resultNodes.get(i + 1);
}
resultNodes.get(resultNodes.size() - 1).next = null;
return resultNodes.get(0);
}
}
解释
方法:
本题解的思路是通过维护两个指针,分别指向奇数位置和偶数位置的节点,然后将偶数位置的节点逐个摘除并接到另一个链表上。最后,将两个链表连接起来。这样可以在一次遍历中完成奇偶分离。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在定义`dummy_left`和`dummy_right`时,它们的作用和必要性是什么?
▷🦆
为什么在处理偶数位置的节点时,需要将`cur.next`设置为`None`?这一步是否会影响链表的完整性?
▷🦆
在将偶数链表接到奇数链表末尾前,为什么不需要检查`dummy_right.next`是否为`None`?这是否可能导致结果链表中出现断链?
▷🦆
循环中使用`odd`变量来控制奇偶位置,这种方式是否有可能在特定情况下导致错误的奇偶节点分离,例如链表节点数量的奇偶性不同时?
▷相关问题
分隔链表
给你一个头结点为 head
的单链表和一个整数 k
,请你设计一个算法将链表分隔为 k
个连续的部分。
每部分的长度应该尽可能的相等:任意两部分的长度差距不能超过 1 。这可能会导致有些部分为 null 。
这 k
个部分应该按照在链表中出现的顺序排列,并且排在前面的部分的长度应该大于或等于排在后面的长度。
返回一个由上述 k
部分组成的数组。
示例 1:

输入:head = [1,2,3], k = 5 输出:[[1],[2],[3],[],[]] 解释: 第一个元素 output[0] 为 output[0].val = 1 ,output[0].next = null 。 最后一个元素 output[4] 为 null ,但它作为 ListNode 的字符串表示是 [] 。
示例 2:

输入:head = [1,2,3,4,5,6,7,8,9,10], k = 3 输出:[[1,2,3,4],[5,6,7],[8,9,10]] 解释: 输入被分成了几个连续的部分,并且每部分的长度相差不超过 1 。前面部分的长度大于等于后面部分的长度。
提示:
- 链表中节点的数目在范围
[0, 1000]
0 <= Node.val <= 1000
1 <= k <= 50