OJ刷题日记:5、二分查找(1)

简介: OJ刷题日记:5、二分查找(1)

1、704.二分查找

题目:


给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9

输出: 4

解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2

输出: -1

解释: 2 不存在 nums 中因此返回 -1


提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。


先看题目这个就是使用二分查找,那么二分查找是什么,就是一个数组假如说是有序的,那么只需要求出中间值就可以进行判断,如果这个值大于target的时候,这个数组右边都是比中间这个值小,同理就可以直到左边都是小的,所以就可以确定两个边界,就是left为0,right为nums.size()-1,所以在循环中就可以持续更新,如果小于就是left=mis+1;大于就是right=left-1;相等就返回,不相等就是返回-1,如下方代码。

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

2、34.在排序数组中查找元素的第一个和最后一个位置

题目:

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [5,7,7,8,8,10], target = 8

输出:[3,4]

示例 2:

输入:nums = [5,7,7,8,8,10], target = 6

输出:[-1,-1]


示例 3:

输入:nums = [], target = 0

输出:[-1,-1]


提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
  • nums 是一个非递减数组
  • -109 <= target <= 109


这个题目就可以看出是要查找一个数的范围,如果找不到就是返回{-1,-1},这里如果直接使用上面一题写的模板时就会很麻烦,所以这里又出现两个变种,分别是查找左区间端点和右区间的做法,这个做法需要注意几个地方,第一个就是循环的条件,这个不能相等,否则就会一直相等然后死循环,如果有相等的时候就是左右两个左边重合就是相等的,所以这里就是判断中点的时候就需要注意一点,一个是在左边,一个是在右边,在这里就可以进行判断条件了,这里是进行分析,如果是找左边的端点的时候就是不能在给left赋值的时候相等了,同理右端也是,也就是在找右端点的时候右边不能等于,所以这时就可以得出条件了,如下方代码实现,就是左边的时候left=left+1;右边的时候就是righ=right+1;然后根据条件就可以写出代码了。

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        if(nums.size()==0) return {-1,-1};
        int left=0,right=nums.size()-1;
        int begin=0;
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]<target) left=mid+1;
            else right=mid;
        }
        if(nums[left]!=target) return {-1,-1};
        else begin=left;
        left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=left+(right-left+1)/2;
            if(nums[mid]<=target) left=mid;
            else right=mid-1;
        }
        return {begin,right};
    }
};

3、35.搜索插入位置

题目:

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

请必须使用时间复杂度为 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后面插入,这个就可以使用上面说的左端点,然后就可以直接使用模板了,如下方代码所示就是套用模板使用。

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

4、69.x的平方根

题目:

给你一个非负整数 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到x中的数据进行暴力求解,也就是每个都进行平方进行判断,是否等于x,如果大于x的时候,还没找到,就是这个数字的前一个,也就是可以把它当成一个数组,1是left,x是right,然后就可以使用右端点的模板,代码如下方,但是这里需要处理一下,就是x为0的时候就是直接返回0,代码如下。

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

目录
相关文章
|
存储 Java C#
30 如何在Swift中实现继承
如何在Swift中实现继承
140 0
|
10月前
|
设计模式 Java 开发者
「全网最细 + 实战源码案例」设计模式——适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,通过引入适配器类将一个类的接口转换为客户端期望的另一个接口,使原本因接口不兼容而无法协作的类能够协同工作。适配器模式分为类适配器和对象适配器两种,前者通过多重继承实现,后者通过组合方式实现,更常用。该模式适用于遗留系统改造、接口转换和第三方库集成等场景,能提高代码复用性和灵活性,但也可能增加代码复杂性和性能开销。
355 28
|
存储 安全 Linux
【开源指南】用二叉树实现高性能共享内存管理
本文介绍了一种使用C++实现的共享内存管理方案,通过借鉴Android property的设计思路,采用二叉树结构存储键值对,提高了数据检索效率。该方案包括设置和获取接口,支持多进程/线程安全,并提供了一个简单的测试示例验证其有效性。
492 109
|
SQL 存储 关系型数据库
SQL判断CHAR类型字段不为空的方法与技巧
在SQL查询中,判断一个CHAR类型字段是否不为空是一个常见的需求
|
NoSQL 算法 Java
接口限流是一种控制访问频率的技术
在高并发场景下,合理的接口限流、防重复提交及接口防抖机制对保障系统稳定性至关重要。本文介绍了如何利用AOP在不改变业务代码的前提下,灵活添加这些功能。具体包括:通过`@AccessLimit`注解实现接口限流,利用Redis进行计数与控制;通过`@RepeatSubmit`注解防止重复提交,确保数据一致性;通过`@AntiShake`注解实现接口防抖,提升用户体验。此外,提供了基于Redisson和Spring Cloud的实现示例。
213 5
|
机器学习/深度学习 自然语言处理 算法
词嵌入(Word Embeddings)
词嵌入(Word Embeddings)
|
文字识别 API 数据处理
印刷文字识别使用问题之对于带钢印的VIN图片如何提高识别准确率
印刷文字识别产品,通常称为OCR(Optical Character Recognition)技术,是一种将图像中的印刷或手写文字转换为机器编码文本的过程。这项技术广泛应用于多个行业和场景中,显著提升文档处理、信息提取和数据录入的效率。以下是印刷文字识别产品的一些典型使用合集。
|
C语言 Windows
C语言中的fopen与fclose函数详解
C语言中的fopen与fclose函数详解
908 1
|
Kubernetes 固态存储 调度
Kubernetes节点亲和性分配Pod
Kubernetes节点亲和性分配Pod
204 0
Kubernetes节点亲和性分配Pod
|
数据采集 缓存 搜索推荐