来源:力扣(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%的用户