持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情
题目描述
给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 insertVal ,使这个列表仍然是循环升序的。
给定的可以是这个列表中任意一个顶点的指针,并不一定是这个列表中最小元素的指针。
如果有多个满足条件的插入位置,可以选择任意一个位置插入新的值,插入后整个列表仍然保持有序。
如果列表为空(给定的节点是 null),需要创建一个循环有序列表并返回这个节点。否则。请返回原先给定的节点。
示例 1:
输入:head = [3,4,1], insertVal = 2
输出:[3,4,1,2]
解释:在上图中,有一个包含三个元素的循环有序列表,你获得值为 3 的节点的指针,我们需要向表中插入元素 2 。新插入的节点应该在 1 和 3 之间,插入之后,整个列表如上图所示,最后返回节点 3 。
示例 2:
输入:head = [], insertVal = 1
输出:[1]
解释:列表为空(给定的节点是 null),创建一个循环有序列表并返回这个节点。
示例 3:
输入:head = [1], insertVal = 0
输出:[1,0]
提示:
- 0 <= Number of Nodes <= 5 * 10^4
- -10^6 <= Node.val <= 10^6
- -10^6 <= insertVal <= 10^6
思路
题目的理解和解都不难,就是要考虑比较多的情况:
- 原始链表为空
- 原始链表只有一个节点
- 原始链表有多个节点,值都相等
- 原始链表有多个节点,至少有2个节点值不同,insertVal在(min,max)范围外
- 原始链表有多个节点,至少有2个节点值不同,insertVal在(min,max)范围内 处理好上述的5种情况,就可以顺藤摸瓜写出解法。
- 原始链表为空,可以直接返回要插入的新节点,注意要形成环,所以新节点的后继要指向自身
- 原始链表只有一个节点,新节点插入在head节点后即可
- 原始链表有多个节点,值都相等;解法同情况2,插入在head节点后即可
- 原始链表有多个节点,至少有2个节点值不同,insertVal在(min,max)范围外;需要找到最后一个值等于max的节点,插入到这个节点后面
- 原始链表有多个节点,至少有2个节点值不同,insertVal在(min,max)范围内;找到第一个满足当前值<=insertVal,后继值>=insertVal的节点,插入在这个节点后面
Java版本代码
class Solution {
public Node insert(Node head, int insertVal) {
// 构建需要插入的节点
Node insertNode = new Node(insertVal);
// 先将节点的后继指向自身
insertNode.next = insertNode;
// 原始列表为空,直接返回insertNode
if (head == null) {
return insertNode;
}
int min = head.val;
int max = head.val;
Node originHead = head;
while (head.next != originHead) {
head = head.next;
min = Integer.min(min, head.val);
max = Integer.max(max, head.val);
}
// 如果max == min,代表原始原始链表中的节点值都相等,或者只有1个节点,这种情况下,直接插入在head后面即可
if (max == min) {
insertNode.next = originHead.next;
originHead.next = insertNode;
return originHead;
}
// 否则,代表原始链表至少有2个值不相等的节点
if (insertVal <= min || insertVal >= max) {
// insertVal在(min, max)范围外时,要找到最后一个等于max值的节点,然后插入在这个节点后面
while (!(head.val == max && head.next.val == min)) {
head = head.next;
}
} else {
// insertVal在(min, max)范围内时,找到一个当前值<=insertVal,后继值>=insertVal的
while (!(head.val <= insertVal && head.next.val >= insertVal)) {
head = head.next;
}
}
insertNode.next = head.next;
head.next = insertNode;
return originHead;
}
}