leetcode 刷题 二分查找 C++ 15个(剑指offer 3个)

目录

模板1 正好等于

704. 二分查找

374. 猜数字大小

 74. 搜索二维矩阵

35. 搜索插入位置 注意如果没找到,返回值是left

69. x 的平方根 注意没找到返回值是r。 还有学会牛顿迭代法 着重

33. 搜索旋转排序数组

81. 搜索旋转排序数组 II

模板 II 左边界

278. 第一个错误的版本

658. 找到 K 个最接近的元素  类似于寻找左边界

162. 寻找峰值   着重

153. 寻找旋转排序数组中的最小值  着重

154. 寻找旋转排序数组中的最小值 II   剑指 Offer 11. 旋转数组的最小数字  着重

模板 III 右边界

34. 在排序数组中查找元素的第一个和最后一个位置 

剑指 Offer 53 - I. 在排序数组中查找数字 I  本题与主站 34 题相同(仅返回值不同)

剑指 Offer 53 - II. 0~n-1中缺失的数字 着重

 labuladong我作了首诗,保你闭着眼睛也能写对二分查找

袁记菜馆一文带你搞定多个二分查找变种题目(视频+绘图)

模板1 正好等于

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while (left <= right) {
            //这里需要注意,计算mid
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target) {
                return mid;
            }else if (nums[mid] < target) {
                //这里需要注意,移动左指针
                left  = mid + 1;
            }else if (nums[mid] > target) {
                //这里需要注意,移动右指针
                right = mid - 1;
            }
        }        
        return -1;
        }
};

2 左边界

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while (left <= right) {
            //这里需要注意,计算mid
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target) {
                right = mid - 1;
            }else if (nums[mid] < target) {
                //这里需要注意,移动左指针
                left  = mid + 1;
            }else if (nums[mid] > target) {
                //这里需要注意,移动右指针
                right = mid - 1;
            }
        }  
		if (left >= nums.size() || nums[left] != target)
			return -1;
        return left;
        }
};

3 右边界

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while (left <= right) {
            //这里需要注意,计算mid
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target) {
                right = mid - 1;
            }else if (nums[mid] < target) {
                //这里需要注意,移动左指针
                left  = mid + 1;
            }else if (nums[mid] > target) {
                //这里需要注意,移动右指针
                left  = mid + 1;
            }
        }  
		if (right < 0 || nums[right] != target)
			return -1;
        return right;
        }
};

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
提示:
  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1;
        while (left <= right) {
            //这里需要注意,计算mid
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target) {
                return mid;
            }else if (nums[mid] < target) {
                //这里需要注意,移动左指针
                left  = mid + 1;
            }else if (nums[mid] > target) {
                //这里需要注意,移动右指针
                right = mid - 1;
            }
        }        
        return -1;
        }
};

374. 猜数字大小

难度简单64

我们正在玩一个猜数字游戏。 游戏规则如下:
我从 1 到 n 选择一个数字。 你需要猜我选择了哪个数字。
每次你猜错了,我会告诉你这个数字是大了还是小了。
你调用一个预先定义好的接口 guess(int num),它会返回 3 个可能的结果(-11 或 0):

-1 : 我的数字比较小
 1 : 我的数字比较大
 0 : 恭喜!你猜对了!

示例 :

输入: n = 10, pick = 6
输出: 6
/** 
 * Forward declaration of guess API.
 * @param  num   your guess
 * @return 	     -1 if num is lower than the guess number
 *			      1 if num is higher than the guess number
 *               otherwise return 0
 * int guess(int num);
 */
//从一开始的,所以low从1开始
class Solution {
public:
    int guessNumber(int n) {
        int low = 1;
        int high = n;
        while (low <= high) {
            int mid = low + (high - low) / 2;
            int res = guess(mid);
            if (res == 0)
                return mid;
            else if (res < 0)
                high = mid - 1;
            else
                low = mid + 1;
        }
        return -1;
    }
};

 74. 搜索二维矩阵

编写一个高效的算法来判断  m x n  矩阵中,是否存在一个目标值。该矩阵具有如下特性:

  • 每行中的整数从左到右按升序排列。
  • 每行的第一个整数大于前一行的最后一个整数。
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        int m = matrix.size();
        if (m == 0) return false;
        int n = matrix[0].size();

        // 二分查找
        int left = 0, right = m * n - 1;
        int mid,midElement;
        while (left <= right) 
        {
            mid = (left + right) / 2;
            midElement = matrix[mid / n][mid % n];
            if (midElement == target) {
                return true;
            }else if (midElement < target) {
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值