1.二分查找
给定一个 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
提示:
- 你可以假设
nums
中的所有元素是不重复的。 n
将在[1, 10000]
之间。nums
的每个元素都将在[-9999, 9999]
之间。
解题思路:
定义左右指针分别指向数组的开头和结尾
从数组的中间数开始找,如果中间数等于需要找的数target就直接返回中间数索引
如果中间数大于target,说明target在左边。
如果中间数小于target,说明target在右边。
var search = function(nums,target){
let left = 0, right = nums.length - 1
while(left <= right){
//中间数
const mid = Math.floor((right - left) / 2) + left
const num = nums[mid]
if(num === target){
return mid
}else if(num > target){
right = mid - 1
}else{
left = mid + 1
}
}
return -1
}
2.第一个错误版本
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 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
解题思路:
定义左右指针,指向1,n
先判断中间的是否为合格产品,如果是,说明第一个错误版本在右边
如果中间的是不合格产品, 说明第一个错误版本在左边也可能是本身
var soultion = function (isBadVersion) {
return function (n) {
let left = 1,right = n
while(left <= right){
const mid = Math.floor((right - left) / 2)
if(isBadVersion(mid)){
right = mid
}else{
left = mid + 1
}
}
return left
}
}
3.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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
解题思路:
定义左右指针 ,指向数组开头和结尾
从中间开始找,如果中间数等于查找数就返回索引,如果中间数大于查找数,说明查找数在左边,如果中间数小于查找数,说明查找数在右边。如果没有找到,就返回此时的left(需要插入的位置)
var searchInsert= function(nums,target){
let left = 0, right = nums.length - 1
while(left <= right){
//中间数
const mid = Math.floor((right - left) / 2) + left
const num = nums[mid]
if(num === target){
return mid
}else if(num > target){
right = mid - 1
}else{
left = mid + 1
}
}
return left
}
来源:力扣算法入门!