【贪玩巴斯】LeetCode力扣算法入门——二分查找 题与题解 //2021-07-22

本文详细解析了LeetCode上的三个关于二分查找的问题,包括在有序数组中查找目标值及其插入位置,同时介绍了如何使用C++实现并优化算法,以O(logn)的时间复杂度解决。讨论了如何在产品开发中应用类似技术减少API调用次数。
摘要由CSDN通过智能技术生成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-search
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

非商业转载

LeetCode力扣刷题记录

题目一:

题目:

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

Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1.

You must write an algorithm with O(log n) runtime complexity.

示例 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
 

提示:

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

解题答案(C++):

class Solution 
{
public:
    int search(vector<int>& nums, int target) 
    {
        int n = nums.size(); // 调用size()函数 计算vector中的长度
        int left = 0,right = n - 1; // 二分法的关键就是定义 左 右index下标值
        int mid = 0; // 定义中间数的index下标值

        while(left <= right) // while循环持续
        {
            mid = left + (right - left)/2; // 计算出中间index下标值
            if(nums[mid] > target) // 判断两种情况 第一种target小于了中间值
            {
                right = mid - 1; // 那么右边的下标值就等于 mid-1 又再次进入while循环
            }
            else if(nums[mid] < target)  // 同理
            {
                left = mid + 1;
            }
            else
                return mid; 
        }
        return -1;
    }
};

46 / 46 个通过测试用例

状态:通过

执行用时: 32 ms

内存消耗: 26.9 MB

讲解参见另一文章:

题目二:

题目:

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

请必须使用时间复杂度为 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
示例 4:

输入: nums = [1,3,5,6], target = 0
输出: 0
示例 5:

输入: nums = [1], target = 0
输出: 0
 

提示:

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为无重复元素的升序排列数组
-104 <= target <= 104

Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You must write an algorithm with O(log n) runtime complexity.

class Solution {
public:
	int searchInsert(vector<int>& nums, int target) {
		int n = nums.size();
		//如果比末尾元素还大,那么返回末尾下标+1也就是数组长度n
		if (target > nums[n - 1]) {
			return n;
		}
		//设置左右两个点代表首尾下标
		int i = 0;
		int j = n - 1;
		//首尾下标不相遇即可循环,相遇代表找到了
		while (i < j) {
			//设置中间点为左下标加上左右下标差的一半
			//(j-i)/2代表的是中间元素的数量不是下标
			//所以前面必须加上一个i
			int mid = i + (j - i) / 2;
			//如果中间值小于target,代表在右半侧
			if (nums[mid] < target) {
				//左坐标就变成中间值+1重新判断
				//i=mid+1是因为nums[mid] != target所以直接右移一位节省时间
				i = mid + 1;
			}
			//否则就是在左半侧同上
			//j没有等于mid-1是因为如果mid=i则j=mid-1则j<i
			//我们需要的是i=j代表插入的位置
			else {
				j = mid;
			}
		}
		//运行到这里代表i=j,i就是我们要找的位置
		return i;
	}
};

答案二:

class Solution 
{
public:
    int search(vector<int>& nums, int target) 
    {
        int n = nums.size();
        int left = 0,right = n - 1;
        int mid = 0;

        while(left <=right)
        {
            mid = left + (right - left)/2;
            if(nums[mid] > target)
            {
                right = mid - 1;
            }
            else if(nums[mid] < target)
            {
                left = mid + 1;
            }
            else
                return mid; 
        }
        return -1;
    }
};

62 / 62 个通过测试用例

状态:通过

执行用时: 4 ms

内存消耗: 9.5 MB

讲解参见另一文章:

题目三:

你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。

假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。

你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。

 
示例 1:

输入:n = 5, bad = 4
输出:4
解释:
调用 isBadVersion(3) -> false 
调用 isBadVersion(5) -> true 
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
示例 2:

输入:n = 1, bad = 1
输出:1
 

提示:

1 <= bad <= n <= 231 - 1

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.

You are given an API bool isBadVersion(version) which returns whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

题目解答:


class Solution {
public:
    int firstBadVersion(int n) 
    {
        int left = 1;
        while(left < n)
        {
            int mid = left + (n-left)/2;
            if(isBadVersion(mid))
                n = mid;
            else
                left = mid + 1;

        }
        return left;
    }
};

执行用时:0 ms, 在所有 C++ 提交中击败了100.00%的用户

内存消耗:5.9 MB, 在所有 C++ 提交中击败了25.70%的用户

讲解参见另一文章:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

贪玩巴斯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值