踩坑二分查找-进阶

文章详细讨论了二分查找算法在处理目标元素存在与不存在的情况时,不同的边界选择、循环退出条件、中间点计算方法以及返回值的影响。通过具体代码示例展示了如何处理查找目标在数组中的位置,以及目标元素不存在时返回预期结果的方法。

针对二分查找查找目标元素的各种情况,以及每一行代码的不同写法的组合所达到的不同效果

前置说明

  1. 关于左右边界的选择
    1. 开区间是指左右边界初始化选取不包括数组内部元素,闭区间反之
    2. 左边界分为开区间和闭区间两种情况
      1. 开区间 left = -1
      2. 闭区间 left = 0
    3. 右边界
      1. 开区间:right = n
      2. 闭区间:right = n - 1
  2. 关于跳出循环的条件判断
    1. left < right:最终跳出循环->left = right + 1
    2. left <= right:->left = right
  3. 关于mid的计算
    1. 一般mid = left + (right - left) / 2
      1. 在java中防止超出数据范围
      2. ex: left = 0,right = 1 那么 mid = 0
      3. 也就是说:以此种方式计算,最终的结果总会落到左边
    2. 使结果落到右边的写法 mid = left + (right - left + 1)/2
      1. ex: left = 0,right = 1 那么 mid = 1
  4. 关于条件判断
    1. nums[mid] >= target
      1. 符合条件的情况下,目标元素在左半部分,更新右边界

实际举例测试各种写法

  • 示例数组:no_repeat_arr = [1, 3, 4, 5, 6, 7, 9, 11, 14, 19]

查找的目标元素存在

  • 如果目标元素存在,则写法较为宽松
def binary_search(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) -1
    while left <= right:
        mid = left + (right - left) // 2
        if nums[mid] >= target:
            right = mid - 1
        else:
            left = mid + 1
            # left = right + 1
    return left
  • 测试结果如下

image.png

  1. 注意事项归纳
  2. 判断条件为left <= right的情况下,最终返回left = right + 1
  3. 判断nums[mid] >= target; right = mid - 1
    1. 此时如果nums[mid] = target目标值将会被舍去
    2. 因为对应的判断是nums[mid] < target; left = mid + 1
      1. 很显然最终返回left是行之有效的方法
  4. 边界情况说明
    1. 如果查找目标数组的第一和最后一个元素
    2. 查找第一个元素:target = 1,left = 0,right = -1
      1. right的值不断减小直到等于-1
    3. 查找最后一个元素:target = 19,left = 9,right = 8
      1. left的值不断增加直到最后 left = 9,right = 8
  5. 返回left和返回right的两种写法
# return left
def binary_search_1(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = left + (right - left) // 2
        # 右半部分元素,包括目标元素被舍弃,所以最终返回 left
        if nums[mid] >= target:
            right = mid - 1
        else:
            left = mid + 1
    return left


# return right
def binary_search(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = left + (right - left) // 2
        # 左半部分元素,包括目标元素被舍弃,所以最终返回 right
        if nums[mid] <= target:
            left = mid + 1
        else:
            right = mid - 1
    return right

查找的目标元素不存在

思考这样一个特殊的场景,需要去寻找目标数组中的一个元素,但是不确定该元素存在与否。想要达到一个预期效果:如果目标元素存在,则返回目标元素索引,如果不存在。ex: [1, 9] target = 8

  1. 想要返回目标元素1的索引,即查找的元素的左边,如果查找的元素小于数组中的元素,希望返回-1.该如何写
  2. 反之想要返回“右边”索引,该如何写。
  3. 或者总期望返回目标元素左边或右边的元素,该如何写
  4. 对上面返回left or right的代码稍作改动即可
def binary_search(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = left + (right - left) // 2
        # 右边部分元素被舍弃
        if nums[mid] >= target:
            right = mid - 1
        else:
            left = mid + 1
    # 边界情况特殊处理
    if len(nums) == left:
        return len(nums) - 1
    if left == -1:
        return -1
    return left - 1 if nums[left] == target else left
def binary_search(nums: List[int], target: int) -> int:
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = left + (right - left) // 2
        if nums[mid] <= target:
            left = mid + 1
        else:
            right = mid - 1
    return left
<think>嗯,用户想要一个为期四个月的PHP全栈开发学习计划,每天3-4小时,使用XAMPP和VSCode,项目驱动。首先,我得确定PHP全栈需要哪些技能,包括前端、后端、数据库,可能还有版本控制和部署。 用户提到了小白,所以得从基础开始。安装XAMPP和VSCode是第一步,可能需要详细的安装步骤,特别是XDebug配置,因为之前的问题里用户遇到了php.ini的问题。引用[1]和[2]提到XDebug配置的常见错误,所以学习计划里要强调正确配置,避免新手。 接下来是知识点分阶段。第一个月打基础,PHP语法、前端三件套,还有数据库基础。每周安排不同的主题,比如第一周安装环境,第二周PHP语法,第三周前端,第四周综合练习。这样逐步递进。 第二个月可以深入后端,比如表单处理、会话管理、文件操作,同时引入MySQL进阶和PHP面向对象。用户提供的引用[3]里有一个表单处理的例子,可以作为一个练习项目,让学习者实践表单提交和数据库插入操作。 第三个月可能需要学框架,比如Laravel,以及前端框架如Bootstrap或Vue.js。这时候项目驱动更重要,比如开发一个博客系统,整合前后端,使用MVC模式。同时,版本控制工具Git也是必须的,教他们如何管理代码。 第四个月做全栈项目,比如电商平台,需要需求分析、前后端分离、RESTful API,最后部署到服务器。这时候会涉及到性能优化和安全性,比如防止SQL注入,引用[3]中的代码存在SQL注入风险,可以提醒他们使用预处理语句。 资源方面,要推荐免费且质量高的教程,比如W3School、PHP官方文档、freeCodeCamp的视频,以及实战练习平台如Codewars。注意事项部分,强调代码规范、安全性和备份,特别是数据库操作和配置文件的安全,引用[2]里的端口号一致问题也要注意。 时间安排上,每周5天,每天3-4小时,两个月分阶段,确保每个阶段有足够的时间练习。项目驱动的话,每个阶段结束都有小项目,最后综合项目巩固所有知识。 需要检查是否有遗漏的部分,比如测试、调试技巧,或者Composer这样的依赖管理工具。另外,部署部分可能需要简单的服务器配置,比如使用XAMPP本地部署,或者免费主机服务。 最后,确保学习计划不要太紧凑,留有时间复习和解决问题。可能还要推荐社区支持,如Stack Overflow,帮助他们在遇到问题时找到解决方案。</think>### PHP全栈开发小白学习方案(4个月) (使用XAMPP+VSCode,项目驱动,含每日学习路线) --- ### 阶段一:环境搭建与基础语法(第1-2周) **目标:完成开发环境配置,掌握基础语法** 1. **环境安装**(3天) - XAMPP安装:重点注意`php.ini`配置,特别是XDebug端口设置(参考[^2]) ```bash [XDebug] zend_extension=xdebug xdebug.remote_enable=1 xdebug.remote_port=9003 # 必须与VSCode配置一致 ``` - VSCode插件:PHP Intelephense、XDebug 2. **PHP基础语法**(7天) - 变量/运算符/流程控制 - 函数/数组/超全局变量`$_GET/$_POST` - 每日练习:BMI计算器、简易计算器 --- ### 阶段二:Web开发基础(第3-6周) **目标:实现动态网页交互** 1. **前端三件套**(10天) - HTML表单处理(参考[^3]案例) - CSS布局实战:Flex/Grid - JavaScript DOM操作 2. **PHP与MySQL**(14天) ```php // 连接数据库示例 $conn = new mysqli("localhost", "root", "", "test"); $stmt = $conn->prepare("INSERT INTO users (name) VALUES (?)"); $stmt->bind_param("s", $name); // 防止SQL注入 ``` - CRUD操作:结合[^3]的留言系统案例改进 - 项目:学生成绩管理系统(含数据增删改查) --- ### 阶段三:框架与进阶开发(第7-10周) **目标:掌握主流开发模式** 1. **Laravel入门**(14天) - 路由/Blade模板/Eloquent ORM - 使用Artisan命令行工具 ```bash php artisan make:model Post -mcr ``` 2. **前后端分离实践**(10天) - RESTful API开发 - AJAX与Fetch API调用 - 项目:TodoList API+前端 --- ### 阶段四:全栈项目实战(第11-16周) **综合项目:电子商务平台** 1. **功能模块** - 用户系统(注册/登录/JWT) - 商品管理(文件上传/缩略图生成) - 支付接口集成(模拟支付) 2. **部署实践** - XAMPP生产模式配置 - `.htaccess`重写规则 - 基础性能优化技巧 --- ### 📚 免费学习资源 | 类型 | 推荐资源 | |------------|--------------------------------------------------------------------------| | 视频教程 | freeCodeCamp PHP全栈课程(YouTube) | | 交互练习 | Codewars PHP题库、W3School在线编辑器 | | 文档 | PHP官方文档、Laravel中文文档 | | 项目源码 | GitHub搜索"php beginner projects" | --- ### ⚠️ 关键注意事项 1. **调试规范** - 所有SQL查询必须使用预处理语句(如[^3]案例存在注入风险) - XDebug断点调试配置验证(参考[^1]配置要点) 2. **学习技巧** - 每天保留30分钟阅读优质代码(如Laravel源码片段) - 使用Git进行版本控制,推荐分支策略: ``` main -> develop -> feature/login ``` --- ### 📅 每日时间分配建议 | 时间段 | 学习内容 | |------------|-----------------------------------| | 19:00-19:30| 复习昨日知识点 | | 19:30-20:30| 视频教程/文档学习 | | 20:30-21:30| 编码实践 | | 21:30-22:00| 整理学习笔记/Git提交 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值