题目
给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 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
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/4ueAj6
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
思路:null时直接自循环然后返回。使用int型的min和max记录链表中的最大最小数据,以此为根据来进行大方向的区分,即是否链表中所有元素均相同(若不做这个区分,后面新增insertval的时候,不好判断是纯的[3,3,3]还是[5,3,3,3,1])。小情况分为两种,分别是插在max和min中间和正常情况插入。
小tips:while()中使用!可以将链表指针停留在自己需要的地方。比如第一个while中的判断条件,使head指针停留在max处,head.next停在min。相当于从头开始遍历。第二个则停留在插入的地方,注意括号和&&!的逻辑位置
代码:
class Solution {
public Node insert(Node he, int x) {
Node t = new Node(x);
if (he == null) {
t.next=t;
return t;
}
Node ans = he;
int min = he.val, max = he.val;
while (he.next != ans) {
he = he.next;
min = Math.min(min, he.val);
max = Math.max(max, he.val);
}
if (min == max) {
t.next = ans.next;
ans.next = t;
} else {
while (!(he.val == max && he.next.val == min)) he = he.next;
while (!(x <= min || x >= max) && !(he.val <= x && x <= he.next.val)) he = he.next;
t.next = he.next;
he.next = t;
}
return ans;
}
}