循环有序列表的插入
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 44 ms, 内存: 15.6 MB
/*
* 问题思路:
* 1. 将链表转换为ArrayList。
* 2. 使用Stream API找到合适的插入点。
* 3. 插入新值并将ArrayList转回循环链表。
*/
import java.util.ArrayList;
import java.util.stream.IntStream;
public class SolutionStream {
static class Node {
public int val;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _next) {
val = _val;
next = _next;
}
}
public Node insert(Node head, int insertVal) {
if (head == null) {
Node newNode = new Node(insertVal);
newNode.next = newNode;
return newNode;
}
ArrayList<Node> nodes = new ArrayList<>();
Node current = head;
do {
nodes.add(current);
current = current.next;
} while (current != head);
int size = nodes.size();
int insertIndex = IntStream.range(0, size)
.filter(i -> (nodes.get(i).val <= insertVal && insertVal <= nodes.get((i + 1) % size).val)
|| (nodes.get(i).val > nodes.get((i + 1) % size).val &&
(insertVal >= nodes.get(i).val || insertVal <= nodes.get((i + 1) % size).val)))
.findFirst()
.orElse(size - 1);
Node newNode = new Node(insertVal, nodes.get((insertIndex + 1) % size));
nodes.get(insertIndex).next = newNode;
return head;
}
}
解释
方法:
本题解的核心思路是在一个循环单调非递减列表中插入一个新元素,同时保持列表的循环单调非递减特性。首先,如果列表为空(head为None),则创建一个新节点并使其成为循环列表。如果列表中只有一个节点,直接在此节点后插入新节点并更新指针。对于多节点的情况,遍历列表寻找插入位置:1. 直接找到两个相邻节点,使得前一个节点的值小于等于插入值且插入值小于等于后一个节点的值;2. 如果遍历一圈后未找到这样的相邻节点,说明插入值应当插入在最大值节点的后面。这种情况下,需要维护一个最大值节点的引用,在遍历过程中更新。最后,将新节点插入到合适的位置。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在循环列表中,如果`insertVal`的值比所有节点的值都要大或都要小,你是如何处理这种情况的?
▷🦆
为什么在找到合适的插入位置后要立即返回头节点,这样做有什么特别的意义吗?
▷🦆
你提到了维护一个`最大值节点的引用`,这是出于什么考虑?是否有可能存在多个最大值,如果是,你是如何选择其中一个作为插入点的?
▷