Python每日一练-----搜索插入的位置

这篇博客介绍了如何在已排序的数组中使用二分查找法找到目标值的索引。当目标值不存在于数组中时,返回其应该插入的位置。解题思路是通过不断缩小查找范围,根据目标值与中间数的比较来移动左右指针,直到找到目标值或确定其插入位置。最后提供了Python代码实现和详细注释。

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

🌤(day31)

目录

📝题目:

题目分析:

解题思路:

🌈代码实现

🌟代码注释


📝题目:

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

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

⭐示例 1:

输入: nums = [1,3,5,6], target = 5

输出: 2

解释说明:目标数所在索引为2

⭐示例 2:

输入: nums = [1,3,5,6], target = 2

输出: 1

解释说明:数组(列表)中没有目标数,将2插入到1和3当中,这是2的索引为1

⭐示例 3:

输入: nums = [1,3,5,6], target = 7

输出: 4

题目分析:

题目要求的是返回目标数的索引(也称下标),如果数组列表nums中没有目标数,那么就需要将其插入到列表中再返回目标数1的索引。题目还要求必须使用时间复杂度为O(logn)的方法来做。(不清楚时间空间复杂度的小伙伴可看:一个小故事带你了解大O表示法

看到O(logn)我们第一时间想到的应该是二分法

解题思路:

按照题目解题时间复杂度的限制,我们使用二分法解题。二分法的精髓,每次解决一半的问题。题目已经将列表nums排序好了,那么我们就可以直接将从首尾开始进行二分。

我们在首尾放置指针,并判断列表nums“中间数”(中间数就是列表最中间的数,如果列表长度为偶数取最中间两个数之一),与目标值target的关系。

✨如果目标值target 正好等于列表的中间数

那么我们返回中间数的索引即可

如果目标值target  > 列表的中间数

那么我们将左(首)指针右移到中间数的右一个位置。

为什么要移到右一个位置?

因为我们已经判断了中间数不等于目标数target,所以我们直接将左指针移到中间数的右一个位置,这样能尽可能缩小排查范围。

如果目标值target <  列表的中间数

同理,我们将右(尾)指针左移到中间数的左一个位置。

我们将着三步操作放入到循环中进行,由于左右指针相遇时说明列表以遍历完成,所以循环进行的条件可以设置为左指针 <= 右指针

那么如和实现题目所说的,当目标值不在列表中是需要将目标值加入到列表并判断其索引?

我们考虑到,如果目标数不在列表当中,遍历完列表也不会出现中间数等于目标值的情况。由循环结束条件我们知道,循环结束时目标值是位于右指针和左指针之间,只是不在列表中无法找到目标值下标。但我们并不需要将目标值真正加入到列表中。因为目标值就在右指针和左指针之间所以我们只需返回右指针的索引+1即可。此时右指针的索引+1即为目标值的索引

🌈代码实现

def searchInsert(nums, target):
    left = 0
    right = len(nums) - 1
    
    while left <= right:
        middle = (left + right) // 2

        if nums[middle] < target:
            left = middle + 1
        elif nums[middle] > target:
            right = middle - 1
        else:
            return middle
    return right + 1

🌟代码注释

def searchInsert(nums, target):
    left = 0  # 初始化左指针
    right = len(nums) - 1  # 初始化右指针

    while left <= right:
        middle = (left + right) // 2  # 中间数的索引
        
        # 依据判断分析移动指针
        if nums[middle] < target: 
            left = middle + 1
        elif nums[middle] > target:
            right = middle - 1
        else:
            return middle
    return right + 1  # 循环结束还未找到目标数索引,返回右指针+1

这里说明右指针初始化的依据,右指针右很多人喜欢初始化未right = len(nums),这并没有对错之分。这二者的区别

当列表nums长度为偶数时

初始化右指针为right = len(nums)则取最中间的两个数时取靠右的那个

初始化右指针为right = len(nums)则取最中间的两个数时取靠左的那个

----------------------------------------------------

如nums = [1, 2, 3, 4]

前者(middle为中间数索引)

middle = (left + right) // 2 = 2

后者

middle = (left + right) // 2 = 1

---------------------------------------------------

还有就是为什么返回的是right+1。

因为当right=left时while循环还会执行,且我们初始化right=len(nums)- 1,所以当列表长度为偶数时我们都是取靠左的中间数,本来目标值是在左右指针之间,现在循环结束左右指针重合到中间数的索引处,所以返回right+1.其实返回left也是一样的结果

今天就到这,明天见。🚀

❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄

<think>我们正在为用户制定一个50天的编程入门训练计划。根据引用[1],这是一本Python入门书籍,采用习方式引导学习,从基础到项。因此,我们将以Python为例,设计一个循序渐进的学习计划,分为基础学习、核心编程、进阶应用实践四个阶段。计划安排:第一阶段(第1-15天):基础语法与概念第二阶段(第16-30天):核心编程与数据结构第三阶段(第31-40天):进阶应用与模块学习第四阶段(第41-50天):项实践详细步骤:第一阶段:基础语法与概念(15天)标:掌握Python基本语法、数据类型、控制结构、函数定义等。每日安排:第1天:安装PythonIDE,学习打印语句,运行第一个程序。第2天:变量简单数据类型(字符串、整数、浮点数)。第3天:列表的基本操作(创建、访问、修改)。第4天:列表的操作(排序、遍历、切片)。第5天:if条件语句(布尔表达式、简单条件判断)。第6天:字典(键值对、访问、添加、修改)。第7天:用户输入while循环(input()函数,while循环控制)。第8天:函数(定义、调用、参数传递)。第9天:函数(返回值、作用域)。第10天:类与对象(类的定义、创建实例)。第11天:类(继承、重写)。第12天:文件异常(读取、写入文件,异常处理)。第13天:模块(导入模块,常用标准库如math,random)。第14天:测试代码(unittest模块)。第15天:第一阶段复习,完成一个综合练习(如简单计算器)。第二阶段:核心编程与数据结构(15天)标:深入理解编程核心概念,掌握常用数据结构算法基础。每日安排:第16天:算法基础(时间复杂度、空间复杂度)。第17天:线性数据结构(栈、队列的实现与应用)。第18天:排序算法(冒泡排序、选择排序)。第19天:排序算法(插入排序、快速排序)。第20天:查找算法(顺序查找、二分查找)。第21天:递归(递归原理、经典问如斐波那契数列)。第22天:树与二叉树(基本概念、遍历方式)。第23天:图的基本概念(表示方法、深度优先搜索广度优先搜索)。第24天:动态规划(基本概念、简单问如爬楼梯)。第25天:贪心算法(基本概念、简单应用)。第26天:字符串操作(常见字符串处理问)。第27天:正则表达式(基本语法、常用函数)。第28天:常用数据结构再深入(堆、哈希表)。第29天:算法综合练习(解决一些中等难度算法)。第30天:第二阶段复习,完成一个综合项(如通讯录管理)。第三阶段:进阶应用与模块学习(10天)标:学习常用第三方库,进行实际应用开发。每日安排:第31天:网络编程(socket基础,TCP/UDP)。第32天:多线程与多进程(基本概念、使用场景)。第33天:数据库操作(SQLite3或MySQL的连接与操作)。第34天:Web开发基础(Flask框架入门,创建简单路由)。第35天:Web开发(模板渲染、表单处理)。第36天:数据科学基础(NumPy数组操作)。第37天:数据可视化(Matplotlib绘图)。第38天:爬虫基础(requests库、BeautifulSoup解析)。第39天:爬虫进阶(Scrapy框架入门)。第40天:第三阶段复习,完成一个综合应用(如简单博客系统)。第四阶段:项实践(10天)标:独立完成一个综合项,巩固所学知识。每日安排:第41天:项(如:简易在线商城、数据分析项、小游戏等),需求分析。第42天:项设计(架构设计、模块划分)。第43-47天:项编码(每天完成1-2个模块)。第48天:项测试与调试。第49天:项文档编写。第50天:项展示与总结,回顾学习过程。学习资源推荐:-书籍:《Python编程:从入门到实践》(引用[1]类似风格)-在线平台:LeetCode、牛客网等平台(算法练习)-第三方库官方文档(如Flask,NumPy等)注意事项:-每天保证2-3小时的学习时间,动手编写代码。-遇到问查阅文档、搜索解决方案,培养解决问的能力。-定期复习前面所学内容。根据引用[2],如果对游戏开发感兴趣,可以在第三阶段加入pygame的学习(例如在第31-40天中安排一天学习pygame基础,然后在项阶段选择开发一个小游戏)。这个计划旨在帮助零基础的学习者在50天内掌握Python编程基础具备一定的项开发能力。实际进度可根据个人情况调整。相关问:1.如何保持学习编程的动力?2.在学习过程中遇到难以理解的概念该怎么办?3.除了Python,还有哪些适合入门的编程语言?</think>以下是一个系统化的**50天编程入门训练计划及学习步骤**,基于Python语言设计(因其易学性广泛应用),结合理论、实践驱动,帮助你从零基础到掌握核心编程能力: --- ### **一、总体阶段划分** | **阶段** | **天数** | **核心标** | |----------------|----------|----------------------------------| | **基础语法** | 第1-15天 | 掌握变量、数据类型、控制结构等基础 | | **核心编程** | 第16-30天 | 深入函数、数据结构、文件操作等 | | **应用实战** | 第31-40天 | 学习常用库(网络/数据库/可视化) | | **项开发** | 第41-50天 | 独立完成1-2个综合项 | --- ### **二、详细学习步骤** #### **第一阶段:基础语法(第1-15天)** 1. **环境搭建**(第1天) - 安装Python(推荐3.8+版本)VS Code编辑器。 - 编写第一个程序:`print("Hello World")`。 2. **变量与数据类型**(第2-4天) - 学习整型、浮点型、字符串、布尔型,例如: ```python age = 25 # 整型 price = 9.99 # 浮点型 name = "Alice" # 字符串 ``` - 练习:用户输入姓名年龄,打印自我介绍。 3. **控制结构**(第5-8天) - `if-else`条件判断(例如判断成绩等级)。 - `for`/`while`循环(例如打印乘法表、猜数字游戏)。 4. **数据结构**(第9-12天) - 列表:`fruits = ["apple", "banana"]` - 字典:`user = {"name": "Bob", "age": 30}` - 练习:管理学生成绩单(增删改查)。 5. **函数基础**(第13-15天) - 定义函数:`def add(a, b): return a + b` - 练习:编写计算器(加减乘除)。 > **资源参考**:书籍《Python编程:从入门到实践》前10章[^1]。 --- #### **第二阶段:核心编程(第16-30天)** 1. **函数进阶**(第16-18天) - 学习递归(例如阶乘计算)、Lambda表达式。 2. **文件操作**(第19-21天) - 读写文本文件(`.txt`)、CSV文件(例如日志分析)。 3. **异常处理**(第22天) - 使用`try-except`捕获错误(例如处理除零错误)。 4. **面向对象(OOP)**(第23-26天) - 类与对象:`class Dog: def __init__(self, name): self.name = name` - 练习:模拟银行账户管理系统。 5. **模块与包**(第27-30天) - 使用标准库(如`math`, `random`),创建自定义模块。 --- #### **第三阶段:应用实战(第31-40天)** 1. **网络请求**(第31-32天) - 使用`requests`库获取API数据(例如天气查询)。 2. **数据库操作**(第33-35天) - SQLite基础:创建表、插入数据(例如用户管理系统)。 3. **数据可视化**(第36-37天) - 用`matplotlib`绘制图表(例如销售数据折线图)。 4. **Web开发基础**(第38-40天) - Flask框架入门:构建简单网页(例如个人博客首页)。 --- #### **第四阶段:项开发(第41-50天)** 1. **选与设计**(第41天) - 选择项方向(如:待办清单、爬虫、数据分析)。 2. **编码实现**(第42-48天) - 分模块开发(前端+后端+数据库),例如: ```python # Flask示例:主页路由 @app.route('/') def home(): return render_template("index.html") ``` 3. **测试与优化**(第49天) - 修复Bug,优化代码性能。 4. **部署与总结**(第50天) - 使用GitHub托管代码,撰写项文档。 > **推荐项**: > - 简易博客系统(Flask + SQLite) > - 疫情数据可视化(requests + matplotlib) > - 单词记忆工具(文件操作 + GUI库如Tkinter) --- ### **三、关键学习原则** 1. **每日实践**:每天至少写1小时代码(如[LeetCode](https://leetcode.com/)简单)。 2. **及时复盘**:每晚记录当日难点(例如:GitHub写日志)。 3. **社区求助**:遇到问优先查官方文档,再使用Stack Overflow。 4. **扩展阅读**:参考《流畅的Python》提升代码质量[^1]。 --- ### 相关问 1. 如何高效调试Python程序? 2. 哪些工具可以提升初学者的代码效率? 3. 如何从入门级项过渡到工业级开发? > 计划可根据基础调整进度,重点在于**持续动手实践**。遇到问可随时提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亖夕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值