当前位置: 首页 > news >正文

LeetCode算法日记 - Day 10: x 的平方根、搜索插入位置

目录

1.  x 的平方根

1.1 题目解析

1.2 解法

1.3 代码实现

2. 搜索插入位置

2.1 题目解析

2.2 解法

2.3 代码实现


1.  x 的平方根

69. x 的平方根 - 力扣(LeetCode)

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

示例 1:

输入:x = 4
输出:2

示例 2:

输入:x = 8
输出:2
解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。

提示:

  • 0 <= x <= 231 - 1

1.1 题目解析

本题要求计算非负整数 x 的算术平方根,保留整数部分(向下取整),不能使用内置开方或指数函数。我们要找的是最大整数 r,满足:r * r <= x,这意味着答案是一个边界值,左边(含自身)的平方小于等于 x,右边的平方大于 x。。

i)区间特性

  • [0, r] 之间的数平方后 ≤ x

  • [r + 1, x] 之间的数平方后 > x ,这样的区间特性非常适合用二分查找来锁定边界

ii)据范围与溢出

在计算平方时可能会超出 32 位整数范围,因此需要使用更大的数据类型(如 long 或 long long)来存储中间结果。

1.2 解法

i)初始化左右边界:left = 0, right = x

ii)循环执行:

  • 取中点:mid = left + (right - left+1) / 2

  • 如果 mid * mid <= x:
    说明 mid 可能是结果,但右边可能还有更大的满足条件的值 → 更新:left = mid 

  • 否则(mid * mid > x):
    说明 mid 太大,答案一定在左半部分 → 更新:right = mid - 1

1.3 代码实现

class Solution {public int mySqrt(int x) {if(x<1){return 0;}long left = 0,right = x;while(left<right){long mid = left + (right-left+1)/2;if(mid*mid<=x){left = mid;}else{right = mid -1;}}return (int)left;}
}

2. 搜索插入位置

35. 搜索插入位置 - 力扣(LeetCode)

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

请必须使用时间复杂度为 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 题目解析

本题要求在一个升序排序的数组中找到目标值 target 的索引,如果不存在则返回它应该被插入的位置。题目明确要求时间复杂度为 O(log n),这意味着要用 二分查找 来完成。

通过分析可得:

i)插入位置的定义
插入位置 index 满足:

  • 在位置 index 之前的所有元素都 小于 target

  • 从位置 index 开始的所有元素都 大于等于 target
    换句话说,index 就是第一个大于等于 target 的元素的下标

ii)为什么判断条件是 nums[mid] >= target

  • 如果 nums[mid] >= target,说明 mid 以及它左边的部分可能包含插入位置,因此需要继续在左半区间搜索。

  • 如果 nums[mid] < target,则可以排除 mid 及其左侧,继续在右半区间搜索。

  • 这道题的关键点在于:第一个大于等于 target 的值可以确定位置,但第一个小于 target 的值不能确定位置,因此判断条件必须用 >=。

iii)终止条件
二分查找不断缩小 [left, right] 的范围,直到 left == right,此时 left(或 right)就是插入位置

iiii)边界情况

  • 如果 target 比所有元素都小,返回 0。

  • 如果 target 比所有元素都大,返回 nums.length。

  • 如果数组中存在 target,直接返回它的第一个出现位置。

2.2 解法

i)区间特性
设插入位置为 index,则:

  • [left, index - 1] 内的所有元素 < target

  • [index, right] 内的所有元素 ≥ targe

这道题的判断依据是,第一个大于 t 的值可以确定位置,但是第一个小的值不可以确定 t 的位置,所以判断条件式 mid>= t

ii)判断条件的核心原因
这道题的判断依据是:第一个大于等于 target 的值可以确定位置,但是第一个小于 target 的值不能确定位置,因为小于 target 的值后面可能还会出现等于 target 的元素。。

iii)二分查找步骤

  • 初始化:left = 0,right = nums.length - 1

  • 计算中点:mid = left + (right - left) / 2

    • 如果nums[mid] >= target:
      说明 mid 落在 [index, right] 区间,mid 以及它左边可能是答案
      → 更新 right = mid

    • 如果 nums[mid] < target:
      说明 mid 落在 [left, index - 1] 区间,答案在右半区间
      → 更新 left = mid + 1

  • 循环直到 left == right,此时 left(或 right)就是插入位置。

2.3 代码实现

class Solution {public int searchInsert(int[] nums, int target) {int left = 0,right = nums.length-1;while(left<right){int mid = left + (right-left)/2;if(nums[mid]>=target){right = mid;}else{left = mid + 1;}}if(nums[left]<target){return left+1;}return left;}
}

http://www.lryc.cn/news/619912.html

相关文章:

  • 大模型微调【1】之入门
  • 农业物联网:现代农业的智慧革命
  • 后端(服务端)的跳转方式-请求转发和重定向
  • 集成电路学习:什么是CV计算机视觉
  • Nginx学习笔记(七)——Nginx负载均衡
  • 深度学习之CNN网络简介
  • 深度学习(4):数据加载器
  • go语言学习笔记
  • 初识神经网络05——构建神经网络3
  • C# 反射入门:如何获取 Type 对象?
  • 深度学习流体力学:基于PyTorch的物理信息神经网络(PINN)完整实现
  • Spring Boot项目通过Feign调用三方接口的详细教程
  • 力扣top100(day02-04)--二叉树 01
  • 阿里云Anolis OS 8.6的公有云仓库源配置步骤
  • 旧版MinIO的安装(windows)、Spring Boot 后端集成 MinIO 实现文件存储(超详细,带图文)
  • oss(阿里云)前端直传
  • 4G模块 ML307A通过MQTT协议连接到阿里云
  • ImportError: Encountered error: Failed to import NATTEN‘s CPP backend.
  • 事件处理与组件基础
  • 飞算JavaAI实现数据库交互:JPA/Hibernate + MyBatis Plus基础功能学习
  • 基于微信小程序的工作日报管理系统/基于asp.net的工作日报管理系统
  • CAD 的 C# 开发中,对多段线(封闭多边形)内部的点进行 “一笔连线且不交叉、不出界
  • 重生之我在公司写前端 | “博灵语音通知终端” | 登录页面
  • [量化交易](1获取加密货币的交易数据)
  • 01数据结构-Prim算法
  • Unity、C#常用的时间处理类
  • Gradle(三)创建一个 SpringBoot 项目
  • C++ 中构造函数参数对父对象的影响:父子控件管理机制解析
  • 【完整源码+数据集+部署教程】火柴实例分割系统源码和数据集:改进yolo11-rmt
  • 学习语言的一个阶段性总结