Python算法题集_搜索插入位置

Python算法题集_搜索插入位置

本文为Python算法题集之一的代码示例

题51:搜索插入位置

1. 示例说明

  • 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

    请必须使用时间复杂度为 O(log n) 的算法。

    示例 1:

    复制代码
    输入: nums = [1,3,5,6], target = 5
    输出: 2

    示例 2:

    复制代码
    输入: nums = [1,3,5,6], target = 2
    输出: 1

    示例 3:

    复制代码
    输入: nums = [1,3,5,6], target = 7
    输出: 4

    提示:

    • 1 <= nums.length <= 104
    • -104 <= nums[i] <= 104
    • nums无重复元素升序 排列数组
    • -104 <= target <= 104

2. 题目解析

- 题意分解

  1. 本题是在已排序的整数数组中查找目标数字的插入位置
  2. 最快方式就是二分法

- 优化思路

  1. 通常优化:减少循环层次

  2. 通常优化:增加分支,减少计算集

  3. 通常优化:采用内置算法来提升计算速度

  4. 分析题目特点,分析最优解

    1. 二分法中可以采用终止条件判断

    2. 可以考虑使用排序列表操作模块bisect

- 测量工具

  • 本地化测试说明:LeetCode网站测试运行时数据波动很大【可把页面视为功能测试】,因此需要本地化测试解决数据波动问题
  • CheckFuncPerf(本地化函数用时和内存占用测试模块)已上传到CSDN,地址:Python算法题集_检测函数用时和内存占用的模块
  • 本题本地化超时测试用例自己生成,详见章节【最优算法】,代码文件包含在【相关资源】中

3. 代码展开

1) 标准求解【二分法查找】

通过二分法查找目标数值应插入位置

页面功能测试,性能一般,超过79%

python 复制代码
import CheckFuncPerf as cfp

class Solution:
 def searchInsert_base(self, nums, target):
     ileft, iright = 0, len(nums)
     while ileft < iright:
         imid = (ileft + iright) // 2
         if nums[imid] >= target:
             iright = imid
         else:
             ileft = imid + 1
     return ileft

aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.searchInsert_base, nums, itarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))
 
# 运行结果
函数 searchInsert_base 的运行时间为 1.00 ms;内存使用量为 4.00 KB 执行结果 = 99999985

2) 改进版一【二分法查找+终止条件判断】

通过二分法查找目标数值应插入位置,检测中进行终止条件判断

页面功能测试,马马虎虎,超过35%

python 复制代码
import CheckFuncPerf as cfp

class Solution:
 def searchInsert_ext1(self, nums, target):
     ileft, iright = 0, len(nums) - 1
     while ileft <= iright:
         imid = (iright - ileft) // 2 + ileft
         if target == nums[imid]:
             return imid
         if target < nums[imid]:
             iright = imid - 1
         else:
             ileft = imid + 1
     return ileft

aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.searchInsert_ext1, nums, itarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))
 
# 运行结果
函数 searchInsert_ext1 的运行时间为 0.00 ms;内存使用量为 0.00 KB 执行结果 = 99999985

3) 改进版二【第三方模块】

使用排序列表操作模块bisect来查找插入位置

页面功能测试,马马虎虎,超过29%

python 复制代码
import CheckFuncPerf as cfp

class Solution:
 def searchInsert_ext2(self, nums, target):
     from bisect import bisect_left
     return bisect_left(nums, target)

aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.searchInsert_ext2, nums, itarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))
 
# 运行结果
函数 searchInsert_ext2 的运行时间为 1.00 ms;内存使用量为 16.00 KB 执行结果 = 99999985

4. 最优算法

根据本地日志分析,最优算法为第2种方式【二分法查找+终止条件判断】 searchInsert_ext1

本题测试数据,似乎能推出以下结论:

  1. 在排序数组上使用二分法查询,性能非常夸张,简直是瞬间定位【1亿的数组,1毫秒定位】
  2. 既然性能不是问题,那么可维护性越好越有利,推荐使用第三种解法
python 复制代码
ilen  = 100000000
isize = ilen // 2
itarget = 0
while isize > 4:
    itarget += isize
    isize = isize // 2
nums = [x for x in range(ilen)]
aSolution = Solution()
result = cfp.getTimeMemoryStr(aSolution.searchInsert_base, nums, itarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))
result = cfp.getTimeMemoryStr(aSolution.searchInsert_ext1, nums, itarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))
result = cfp.getTimeMemoryStr(aSolution.searchInsert_ext2, nums, itarget)
print(result['msg'], '执行结果 = {}'.format(result['result']))

# 算法本地速度实测比较
函数 searchInsert_base 的运行时间为 1.00 ms;内存使用量为 4.00 KB 执行结果 = 99999985
函数 searchInsert_ext1 的运行时间为 0.00 ms;内存使用量为 0.00 KB 执行结果 = 99999985
函数 searchInsert_ext2 的运行时间为 1.00 ms;内存使用量为 16.00 KB 执行结果 = 99999985

5. 相关资源

本文代码已上传到CSDN,地址:Python算法题源代码_LeetCode(力扣)_搜索插入位置

一日练,一日功,一日不练十日空

may the odds be ever in your favor ~

相关推荐
珹洺39 分钟前
C++从入门到实战(十)类和对象(最终部分)static成员,内部类,匿名对象与对象拷贝时的编译器优化详解
java·数据结构·c++·redis·后端·算法·链表
林泽毅39 分钟前
SwanLab硬件监控:英伟达、昇腾、寒武纪
python·深度学习·昇腾·英伟达·swanlab·寒武纪·训练实战
一 乐42 分钟前
网红酒店|基于java+vue的网红酒店预定系统(源码+数据库+文档)
java·开发语言·数据库·毕业设计·论文·springboot·网红酒店预定系统
写bug的小屁孩43 分钟前
移动零+复写零+快乐数+盛最多水的容器+有效三角形的个数
c++·算法·双指针
DARLING Zero two♡1 小时前
C++底层学习精进:模板进阶
开发语言·c++·模板
飞川撸码1 小时前
【LeetCode 热题100】208:实现 Trie (前缀树)(详细解析)(Go语言版)
算法·leetcode·golang·图搜索算法
这就是编程2 小时前
自回归模型的新浪潮?GPT-4o图像生成技术解析与未来展望
人工智能·算法·机器学习·数据挖掘·回归
勘察加熊人2 小时前
c++生成html文件helloworld
开发语言·c++·html
小哲慢慢来2 小时前
解决auto_gptq安装问题
python
羑悻的小杀马特2 小时前
【狂热算法篇】探寻图论幽径:Bellman - Ford 算法的浪漫征程(通俗易懂版)
c++·算法·图论·bellman_ford算法