704二分查找

本文详细介绍了二分查找算法的实现过程,包括代码实现和解题思路。通过示例代码展示了如何在有序数组中查找目标值,并讨论了不同情况下的边界处理。此外,还总结了二分查找在不同场景下的三种常见变体:正常查找、查找左边界和查找右边界。文章强调了防止溢出的技巧以及理解二分查找条件的重要性。
摘要由CSDN通过智能技术生成

题目描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ij5mOf5t-1631589145189)(C:\Users\落雨\AppData\Roaming\Typora\typora-user-images\image-20210830185956018.png)]

解题思路

代码实现

#include <iostream>
#include <vector>
#include "704二分查找.h"
using namespace std;
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)
		{
			left++;
		}
		else if (nums[mid] > target) {
			right--;
		}
		else
		{
			return mid;
		}

	}
	return -1;
}
int main()
{
	int a[7] = { 1, 2, 3, 4, 5, 6, 7 };
	vector<int> nums(a, a+7);
	int target = 8;
	int i=search(nums, target);
	cout << i << endl;
}

题目链接

实现代码的思路

使用二分查找的条件

二分查找使用的条件是按排好的顺序数组进行查找

while循环判断的条件

正序就是左边小于等于右边,当大于右边时跳出循环,输出未找到时的规定数据

里面判断条件

数据中间的数跟目标数据进行比较,当中间数据大于目标值,left向左移动
当中间数据小于目标值,right向右移动
剩下一种等于目标值然后进行返回

获得的收获

算两数之间的中间数值时要可以使用左边数据+(右边数据-左边数据)/2

这样数据就有更小的可能性进行溢出

二分法各种情况汇总

对于寻找左右边界的二分搜索,常见的手法是使用左闭右开的「搜索区间」,我们还根据逻辑将「搜索区间」全都统一成了两端都闭,便于记忆,只要修改两处即可变化出三种写法:


int binary_search(int[] nums, int target) {
    int left = 0, right = nums.length - 1; 
    while(left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1; 
        } else if(nums[mid] == target) {
            // 直接返回
            return mid;
        }
    }
    // 直接返回
    return -1;
}

int left_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 别返回,锁定左侧边界
            right = mid - 1;
        }
    }
    // 最后要检查 left 越界的情况
    if (left >= nums.length || nums[left] != target)
        return -1;
    return left;
}


int right_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 别返回,锁定右侧边界
            left = mid + 1;
        }
    }
    // 最后要检查 right 越界的情况
    if (right < 0 || nums[right] != target)
        return -1;
    return right;
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值