题目链接:https://leetcode.cn/problems/4ueAj6/description/
题目大意:给出一个循环链表中间的某个结点的指针head
(这个并非真正的头),这个链表从头到尾是非递减的,唯一可能出现递减的地方是【尾部连回头部】处。现在给一个值insertVal
,要求将该值插入链表中,保持非递减性质不变。返回的还是原来的head
指针。
思路:(1)先考虑正常的从头到尾非递减的情况,如果插入值val
与某个结点值nowv
相同,那么直接插到其后面就行。否则无论是大了还是小了,都得再往后递归。
(2)如果刚好碰到尾部接头部处,那么如果val
比尾部值大或者比头部值小,都可以直接插在尾部值后。否则往后递归。
(3)有一种特殊情况是全链表的元素相同。此时我们无法找到(1)(2)中所谓的【尾部接到头部】处(因为不存在nowv > nxtv
的情况了),因此单独做判断。这这种情况,val
插到任意处都行。
完整代码
cpp
class Solution {
public:
void inop(Node* nd, int val, Node* res) {
int nowv = nd->val;
if (val == nowv) {
Node* tmp = nd->next;
nd->next = res;
res->next = tmp;
return;
}
int nxtv = nd->next->val;
if (nowv == nxtv)
inop(nd->next, val, res);
else if (nowv < nxtv) {
if (val < nowv)
inop(nd->next, val, res);
else { // val > nowv
if (val <= nxtv) {
res->next = nd->next;
nd->next = res;
return;
}
else
inop(nd->next, val, res);
}
}
else { // nowv > nxtv, final node
if (val >= nowv) {
res->next = nd->next;
nd->next = res;
return;
}
else { // val < nowv
if (val <= nxtv) {
res->next = nd->next;
nd->next = res;
return;
}
else // val > nxtv
inop(nd->next, val, res);
}
}
}
Node* insert(Node* head, int insertVal) {
Node* res = new Node(insertVal);
if (head == nullptr) {
res->next = res;
return res;
}
Node* temp = head->next;
int headv = head->val;
bool flag = true;
while (temp != head) {
if (temp->val != headv) {
flag = false;
break;
}
temp = temp->next;
}
if (flag) {
res->next = head->next;
head->next = res;
return head;
}
inop(head, insertVal, res);
return head;
}
};