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
提示:
- 你可以假设 nums 中的所有元素是不重复的。
- n 将在 [1, 10000]之间。
- nums 的每个元素都将在 [-9999, 9999]之间。
解题分析及思路:
这道题是一个经典的二分查找问题。在升序数组 nums 中寻找目标值 target,对于特定下标 i,比较 nums[i] 和 target 的大小:
- 如果 nums[i] = target,则下标 i 即为要寻找的下标;
- 如果 nums[i] > target,则 target 只可能在下标 i 的左侧;
- 如果 nums[i] < target,则 target 只可能在下标 i 的右侧。
二分查找过程:
- 定义查找的范围 [left, right],初始查找范围是整个数组。
- 每次取查找范围的中点 mid,比较 nums[mid] 和 target 的大小:
- 如果相等,则 mid 即为要寻找的下标,直接返回 mid。
- 如果 nums[mid] > target,则目标值 target 只可能在下标 mid 的左侧,将 right 指针移动到 mid - 1。
- 如果 nums[mid] < target,则目标值 target 只可能在下标 mid 的右侧,将 left 指针移动到 mid + 1。
- 重复步骤 2,直到 left > right 时结束查找。
- 如果 left > right,说明整个数组已经搜索完毕,但仍未找到目标值,返回 -1。
func search(nums []int, target int) int {
var left, right = 0, len(nums) - 1
for left <= right {
mid := left + (right-left)/2
if nums[mid] == target {
return mid
} else if nums[mid] > target {
right = mid - 1
} else {
left = mid + 1
}
}
return -1
}
复杂度:
- 时间复杂度:O(logN),其中 N 是数组的长度。
- 空间复杂度:O(1)。
执行结果:
- 执行耗时:26 ms,击败了60.66% 的Go用户
- 内存消耗:6.5 MB,击败了50.75% 的Go用户