708. Insert into a Cyclic Sorted List

本文详细解析了在循环有序链表中插入新节点的方法,包括处理多种特殊情况,如空链表、所有节点值都大于或小于新节点值的情况。文章提供了具体的实现思路和代码示例,同时指出了常见的错误点,帮助读者深入理解并正确实现算法。

708. Insert into a Cyclic Sorted List


Given a node from a cyclic linked list which is sorted in ascending order, write a function to insert a value into the list such that it remains a cyclic sorted list. The given node can be a reference to any single node in the list, and may not be necessarily the smallest value in the cyclic list.

If there are multiple suitable places for insertion, you may choose any place to insert the new value. After the insertion, the cyclic list should remain sorted.

If the list is empty (i.e., given node is null), you should create a new single cyclic list and return the reference to that single node. Otherwise, you should return the original given node.

The following example may help you understand the problem better:
在这里插入图片描述
In the figure above, there is a cyclic sorted list of three elements. You are given a reference to the node with value 3, and we need to insert 2 into the list.
在这里插入图片描述
The new node should insert between node 1 and node 3. After the insertion, the list should look like this, and we should still return node 3.

方法1:

思路:

注意是sorted。从head出发,目标是找到最后一个小于等于新数字的节点,称为cur,下一个节点称为next,那么我们就可以把新数字插在中间。要处理几种corner cases:

  1. 所有数字都大于new:要找到最大值作为cur,最小值作为next
  2. 所有数字都小于等于new:要找到最大值作为cur,最小值作为next
  3. 空链:创建一个新的节点返回

通过head,我们可以提前判断一下,如果为空,落入第三种情况。遍历开始之后,几种cases需要处理:1. 出现cur <= new <= next, 这种情况只要出现就可以创建返回。2. 出现cur > next,也就是后半部没有合适的插入点,此时可以标记一个end = cur继续循环。可能在前半部分被第一种case打断,也可能回到head都没有找到合适的点。后一种情况可以直接跳掉之前记录的尾节点插入。

易错点

  1. test case全部相等:理论上此时可以在任意位置插入,但如下方法会在循环一圈后退出,如果end没有被赋值,在下一步insert会抛出nullptr错误。解决办法就是修改end的赋值条件为cur > next为cur >= next。
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;

    Node() {}

    Node(int _val, Node* _next) {
        val = _val;
        next = _next;
    }
};
*/
class Solution {
public:
    Node* insert(Node* head, int insertVal) {
        if (!head) {
            Node* node = new Node(insertVal, nullptr);
            node -> next = node;
            return node;
        } 
        
        Node * end = nullptr, * cur = head, * next = head -> next;
        while (true) {
            if (cur -> val <= insertVal && next -> val >= insertVal) {
                insert(cur, next, insertVal);
                return head;
            }
            if (cur -> val >= next -> val) end = cur;
            cur = next;
            next = next -> next;
            if (cur == head) break;
        }
        insert(end, end -> next, insertVal);
        return head;
    }
    
    void insert(Node* cur, Node* next, int insertVal) {
        Node* node = new Node(insertVal, next);
        cur -> next = node;
    }
};

做一些化简:

  1. 当遇到拐点的时候,可以直接获知new是否小于最小或大于最大,可以直接退出
  2. 循环可以不用画满一周整,如果在最后一步之前都没有被任意一种case(遇到合适点或者遇到拐点)打断,那么最后一个未经检查的间隙一定是需要插入的间隙。因为要不然这个点就是两者之一,要不然就是全部相等的corner case。算是一个trick。
  3. 但这时cur > next时才算极值点,因为不可以radically的打断。
class Solution {
public:
    Node* insert(Node* head, int insertVal) {
        if (!head) {
            Node* node = new Node(insertVal, nullptr);
            node -> next = node;
            return node;
        } 
        
        Node * cur = head, * next = head -> next;
        while (next != head) {
            if (cur -> val <= insertVal && next -> val >= insertVal) break;
			if (cur -> val > next -> val && (insertVal <= next -> val || insertVal >= cur -> val)) break;
            
            cur = next;
            next = next -> next;
        }
        cur -> next = new Node(insertVal, next);
        return head;
    }
};
内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值