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;
    }
};

目录
相关文章
|
6月前
|
算法 容器
OJ刷题日记:2、双指针(2)
OJ刷题日记:2、双指针(2)
41 0
|
6月前
OJ刷题日记:3、滑动窗口(1)
OJ刷题日记:3、滑动窗口(1)
53 0
|
6月前
|
算法 测试技术
OJ刷题日记:1、双指针(1)
OJ刷题日记:1、双指针(1)
52 0
|
6月前
|
算法 C++ 索引
OJ刷题日记:4、滑动窗口(2)
OJ刷题日记:4、滑动窗口(2)
60 0
|
6月前
|
算法
六六力扣刷题数组之再刷二分法
六六力扣刷题数组之再刷二分法
43 0
|
索引 Cloud Native
【刷题日记】654. 最大二叉树
【刷题日记】654. 最大二叉树
|
算法 测试技术 Cloud Native
【刷题日记】2104. 子数组范围和
对于很久没有刷题的我来说,突然开始也开始刷题了,不为别的,已经习惯参与掘金的活动了,同时也可以促进自己再回顾一下算法题,毕竟长时间不练,真的就生疏了
|
算法 Java 测试技术
Leetcode刷题笔记:二分查找算法
LeetCode 对于数组查询算法之一的二分查找算法的简单认识。
101 0
|
机器学习/深度学习 C语言
OJ刷题之旅(1)
OJ刷题之旅(1)
|
机器学习/深度学习
剑指Offer--LeetCode刷题篇
剑指Offer--LeetCode刷题篇