题目
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
class Solution {
public:int search(vector<int>& nums, int target) {}
};
题解思路
题目分析:
- 数组:有序 -> 升序,元素不重复;
- 返回值:成功 -> 下标,不成功 -> -1;
- 基于以上可以采用二分法
二分法: 有 [left, right] 和 [left, right)两种,主要区别是 right 的取值
- [left, right]:左闭右闭,
right = nums.size() - 1
, left == right有意义,所以while(left <= right)
。- if (nums[mid] > target) ,说明需要更新 right,因为 区间是左闭右闭的,当前nums[mid] > target,说明nums[mid] 一定不是 target,即说明接下来搜索的区间是不包含该值的,所以 right = mid - 1;若right = mid的话,会导致mid这个对应的值又进入了下一轮的搜索。
- if (nums[mid] < target) left = mid + 1;
- if (nums[mid] = target) return mid;
- [left, right):左闭右开,
right = nums.size()
, left == right不合法,所以while(left < right)
。- if (nums[mid] > target) ,说明需要更新 right,当前nums[mid] > target,说明接下来搜索的区间不包含nums[mid]的,由于区间是左闭右开的,更新后的搜索区间就是不包含right的,所以 right = mid;
- if (nums[mid] < target) left = mid + 1;
- if (nums[mid] = target) return mid;
代码
左闭右闭[left, right]
#include <vector>
#include <iostream>
using namespace std;class Solution {
public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;while(left <= right){int 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;}
};
// @lc code=end
int main() {Solution obj;vector<int> vec = {0,2,3,6,8,9};int target = 6;int res = obj.search(vec, target);if(res != -1){cout << "成功success: " << res << endl;} else {cout << "fail: " << -1 << endl;}
}
时间复杂度:O(log n)
空间复杂度:O(1)
左闭右开[left, right)
class Solution {
public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size(); while(left < right){int mid = left + (right - left) / 2;if(nums[mid] > target){right = mid;}else if(nums[mid] < target){left = mid + 1;}else{return mid;}}return -1;}
};
// @lc code=end
int main() {Solution obj;vector<int> vec = {0,1,2,3,6,7,8,9,10,12};int target = 11;int res = obj.search(vec, target);if(res != -1){cout << "成功success: " << res << endl;} else {cout << "fail: " << -1 << endl;}
}