【数组】二分查找

题目链接:二分查找
关键点:
【1】数组为有序数组;
【2】数组中无重复元素(有重复元素,则找到的下标不唯一)。
思路:二分法对于区间的判定非常重要,一般有[Left,Right]左闭右闭和[Left,Right)左闭右开两种区间。因此区间不同,写法也不同。

1)左闭右闭区间写法

#include <iostream>
#include <vector>

class Solution
{
public:
	int search(std::vector<int>& nums, int target)
	{
		int left = 0;									// 左边界
		int right = nums.size() - 1;					// 右边界,right作为下标使用,所以需要-1
		while (left <= right)							// nums[right]可以取到,left <= right有意义
		{
			int middle = left + ((right - left) / 2);	// 等同于(left + right)/2,但可避免left + right溢出的可能
			if (nums[middle] < target)					// 说明target在[middle+1,right]区间
			{
				left = middle + 1;						// 更新左边界left
			}
			else if(nums[middle] > target)				// 说明target在[left,middle-1]区间
			{
				right = middle - 1;
			}
			else										// 说明nums[middle] == target
			{
				return middle;
			}
		}
		return -1;										// 未找到目标
	}
};
int main()
{
	std::vector<int> vec = { 1,2,3,4,5,6,7,8,9 };
	Solution s;
	int ret = s.search(vec, 6);
	std::cout << ret << std::endl;
	return 0;
}

2)左闭右开区间写法

#include <iostream>
#include <vector>

class Solution
{
public:
	int search(std::vector<int>& nums, int target)
	{
		int left = 0;									// 左边界
		int right = nums.size();					    // 右边界,因为是开区间,所以不用-1
		while (left < right)							// nums[right]不可能取到,因此left < right
		{
			int middle = left + ((right - left) >> 1);	// 右移一位相当于除2 
			if (nums[middle] < target)					// 说明target在[middle+1,right)区间
			{
				left = middle + 1;						// 更新左边界left
			}
			else if(nums[middle] > target)				// 说明target在[left,middle)区间
			{
				right = middle;
			}
			else										// 说明nums[middle] == target
			{
				return middle;
			}
		}
		return -1;										// 未找到目标
	}
};
int main()
{
	std::vector<int> vec = { 1,2,3,4,5,6,7,8,9 };
	Solution s;
	int ret = s.search(vec, 6);
	std::cout << ret << std::endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值