LC 剑指 Offer II 029. 排序的循环链表 (opens new window) (opens new window)
中等
# 问题描述
给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 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 * 104
-106 <= Node.val <= 106
-106 <= insertVal <= 106
注意:本题与主站 708 题相同:https://leetcode-cn.com/problems/insert-into-a-sorted-circular-linked-list/ (opens new window)
# 一次遍历
分情况讨论进行处理:
- 当 为空时,创建一个新的值为 的节点,并将它的 指向自己,形成循环链表,返回该节点。
- 当 不为空时,遍历链表,使用 表示当前遍历到的节点,有以下几种情况:
- 若链表中存在某个地方,使得值为 的节点插入后依然使得循环链表满足单调非递减,即 ,此时创建值为 的节点,将节点的 指向,再插入到 $curr 之后。
- 若链表不存在某个地方,使得值为 的节点插入后依然使得循环链表满足单调非递减,那么 必然是大于等于链表中的最大值或小于等于链表中的最小值,能插入的地方只有是当前链表最大最小值交汇的地方,该位置,此时创建值为 的节点,将该节点的 指向 ,再插入到 之后。
- 若链表循环了一圈 ,依然没找到能够插入的点,此时链表中的所有值都相同,只需将创建值为 的节点插入到任意位置即可,因为最终判断是在 的情况,所以将新创建的值为 的节点插入到 之后,该节点的 指向 形成循环链表即可
/**
* // Definition for a Node.
* function Node(val, next) {
* this.val = val;
* this.next = next;
* };
*/
/**
* @param {Node} head
* @param {number} insertVal
* @return {Node}
*/
var insert = function (head, insertVal) {
if (!head) {
head = new Node(insertVal)
head.next = head
return head
}
let curr = head
while (true) {
if (curr.next === head) {
const node = new Node(insertVal)
node.next = head
curr.next = node
return head
} else if (
(curr.val <= insertVal && insertVal <= curr.next.val) ||
(curr.val > curr.next.val && (insertVal >= curr.val || insertVal <= curr.next.val))
) {
const node = new Node(insertVal)
node.next = curr.next
curr.next = node
return head
} else {
curr = curr.next
}
}
}
- 时间复杂度:,需要遍历链表一次找到能够插入的节点。
- 空间复杂度:
上次更新: 2023/01/31 19:48:05
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 , 转载请注明出处!