leetcode-Search Insert Position

本文介绍LeetCode中搜索插入位置题目的两种解法:线性查找与二分查找。线性查找简单直观但效率较低,二分查找更高效但实现稍复杂。通过详细分析帮助读者理解不同算法的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题链接:https://leetcode.com/problems/search-insert-position/

我在github上的leetcode仓库:https://github.com/cooljacket/leetcodes

题意

给定一个排好序的数组(升序)和一个数字target。
1. 如果target在数组里,返回它的位置;
2. 否则返回它插入到数组后保持数组有序的位置。

思路1-线性查找

线性从后往前查找,直到找到,或者遇到比它小的值。

评价:这个实现很简单,虽然能够AC,不过时间复杂度为O(n),利用好原数组有序的性质,可以有更好的办法!(见思路2)

class Solution {
public:
    // 1)线性扫描
    int searchInsert(vector<int>& nums, int target) {
        int len = nums.size(), pos = len - 1;
        while (pos >= 0 && nums[pos] >= target) {
            if (nums[pos] == target)
                return pos;
            --pos;
        }
        return pos + 1;
    }
};

思路2-二分查找

对于有序数组的查找,肯定要想到二分啊。不过这里找不到的话,要返回target插入后的位置,这个有点麻烦,如何确定这个位置呢?

假设数组是[1, 3, 5, 7, 9]
分类讨论一下,其实总的只有三种情况是找不到的:
1)从左边溢出区间,比如target=0,最后的情况是left = right = 0,然后right - 1变成-1,跳出while循环,返回值应该是right + 1 = 0;
2)从右边溢出区间,比如target=10,最后的情况是left = right = 4,然后left + 1变成5,跳出while循环,返回值应该是right + 1 = 5;
3)处于区间的两个值之间,比如target=8位于7和9之间,最后的情况是left = right = 3,然后left + 1变成4,跳出while循环,返回值应该是right + 1 = 4。
综上所述,如果找不到,直接返回right + 1就是对的!!!

评价:虽然二分法很高效,复杂度为O(log n),不过分析起来没有线性查找那样直白,如果不是老司机,对于“找不到”的情况可能有点不知所措。(我也不是老司机)

class Solution {
public:
    // 2)二分法!注意分析最后为什么是right + 1,找不到分三种情况~
    // a) 从左边溢出区间;b)从右边溢出区间;c)陷于区间上两个相邻的值之间。
    int searchInsert(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1, mid;
        while (left <= right) {
            mid = (left + right) >> 1;
            if (nums[mid] == target)
                return mid;
            if (nums[mid] < target)
                left = mid + 1;
            else
                right = mid - 1;
        }
        return right + 1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值