题目概述(力扣)
给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 insertVal ,使这个列表仍然是循环升序的。
给定的可以是这个列表中任意一个顶点的指针,并不一定是这个列表中最小元素的指针。
如果有多个满足条件的插入位置,可以选择任意一个位置插入新的值,插入后整个列表仍然保持有序。
如果列表为空(给定的节点是 null),需要创建一个循环有序列表并返回这个节点。否则。请返回原先给定的节点。
解题思路
使用双指针作为基本实现方法,主要针对不同的情况进行不同的情况处理,主要分为以下五种情况:
1.插入的数据在链表中处于中间值部分(链表中目前已存在比它大的值,也存在比它小的值)对于这种情况,我们只需要使用双指针进行遍历,cur和next,当插入的值大于cur元素的值并且小于next元素值时,直接将与该元素插入该位置即可
2.当前链表不存在或者只存在一个元素
当链表中只存在一个元素时,无论插入的元素值与原来元素值的大小关系,直接插入到当前元素后面即可,由于考虑到是链表的数据结构,我们没有办法直接求其长度,所以如果cur指针重新回到了head结点,则认为这就是这个结点应该插入的位置
3.当前链表存在多个元素,但是每个元素的值均相等,由于没办法通过比较元素大小来判断元素的插入位置,所以依然是当cur指针指回head结点时,在此位置进行插入即可
4.当前插入元素的值大于当前链表中的全部元素,找到链表中最大和最小值的交界处进行插入即可
5.当前插入元素的值小于当前链表中的全部元素,找到链表中最大和最小值的交界处进行插入即可
代码实现
class Solution {
public Node insert(Node head, int insertVal) {
//实现思路:使用双指针遍历链表
//非空校验
if(head==null){
head=new Node(insertVal);
head.next=head;
return head;
}
//插入的元素值处于链表元素值大小的中间位置,进行遍历循环
Node next=head.next;
Node cur=head;
//进行遍历
boolean flag=true;
Node newNode=new Node(insertVal);
while(flag){
if(insertVal>=cur.val&&insertVal<=next.val){
//进行插入结点
newNode.next=cur.next;
cur.next=newNode;
return head;
}
//如果是当前链表中不存在比要插入的值大或者小的元素
if(cur.next.val<cur.val&&(cur.next.val>=insertVal||cur.val<insertVal)){
newNode.next=cur.next;
cur.next=newNode;
return head;
}
//处理只有一个结点或者结点全相等
if(cur.next==head){
//链表中只有一个元素或者所有的元素的值均相等
newNode.next=head;
cur.next=newNode;
return head;
}
cur=cur.next;
next=next.next;
}
return head;
}
}