当前位置: 代码迷 >> 综合 >> leecode 704 二分查找
  详细解决方案

leecode 704 二分查找

热度:59   发布时间:2023-12-16 23:38:48.0

二分法

  • 704. 二分查找
  • 35. 搜索插入位置

704. 二分查找

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

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

代码:

class Solution {
    
public:int search(vector<int>& nums, int target) {
    int left = 0;int right = nums.size() - 1;while(left <= right){
    int middle = left + ((right-left)>>1);if(nums[middle] < target){
    left = middle + 1;}else if(nums[middle] > target){
    right = middle - 1;}else{
    return middle;}}return -1;}
};

解释:
1. (right - left) >> 1相当于(right - left) / 2,
>>是右移运算符,假设x=5,那么x的二进制为0101,x>>1表示x右移1位,即把最右边一位的1删掉,变为010,此时x=2。
2. middle = (left + right) / 2换成middle = left + (right - left) / 2,再换成middle = left + ((right-left)>>1)。
第一个改进是因为 (left + right) 可能会溢出,第二个改进是为了运算更快。
3. 循坏不变量,区间的定义要小心,建议看卡哥的评论。
4. 题目描述中含有有序数组和无重复元素,都可以想想是否可以使用二分法

35. 搜索插入位置

题目描述:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
思路:目标值在数组所有元素之前;目标值等于数组中某一个元素;
目标值插入数组中的位置;目标值在数组所有元素之后。

代码如下:二分法

class Solution {
    
public:int searchInsert(vector<int>& nums, int target) {
    int n = nums.size();int left = 0;int right = nums.size() - 1;while(left <= right){
    int mid = left + ((right - left) >> 1);if(nums[mid] > target){
    right = mid - 1;}else if(nums[mid] < target){
    left = mid + 1;}else{
    return mid;}}return right + 1;}
};

ps:循环不变量是指一种在整个循环过程中保持不变的性质,它必须在以下3种情况下均保持不变,且该性质在循环终止后能证明算法的正确性。
(1)初始化(循环初始化后,循环条件测试前)
(2)迭代(第 n 次迭代后,第 n+1 次迭代前)
(3)结束(循环终止即循环条件判断为 false 时)