持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情
前言
今天的题目为中等,碰到的是以前都没有碰到过的node结点类型,但是要是能够搞懂其中的规律,这道题就会变得非常的简单
每日一题
今天的题目是 剑指 Offer II 029. 排序的循环链表,难度为中等
-
给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 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
题解
模拟
题目是很简单的模拟题目,我们需要在一个有序的升序node列表当中找到题目给我们的那个值能放在那个位置,那就是可以通过next不断地循环node结点,然后通过对比前后的val找到放的位置。
并且我们通过题目给出的定义node的class,能够得到定义一个node节点的方法,可以通过 new Node() 的方式来进行定义
/**
* Definition for node.
* class Node {
* val: number
* next: Node | null
* constructor(val?: number, next?: Node) {
* this.val = (val===undefined ? 0 : val);
* this.next = (next===undefined ? null : next);
* }
* }
*/
然后就是需要知道,一个循环的node列表,他们之间的关系是下图这样的
要是我们需要在其中插入一个值,那么我们可以新建一个节点,把节点的next设定为下一个结点,上一个结点的next设定为新节点。
那么在知道了这些之后,这道题就只是简单的去结点当中查找结点的位置,值的注意的是,循环结点只有一个的时候,它的next就是它本身,所以我们要判断一个原先的结点就是空的情况,进行单独的处理。
function insert(head: Node | null, insertVal: number): Node | null {
const newNode = new Node(insertVal)
if (head == null) {
newNode.next = newNode
return newNode
}
let node = head
while (node.next != head) {
if (node.val <= insertVal && insertVal <= node.next.val) {
break
}
if (node.val > node.next.val && (node.val <= insertVal || insertVal <= node.next.val)) {
break
}
node = node.next
}
newNode.next = node.next
node.next = newNode
return head
}