「二分搜索Binary Search」

这篇具有很好参考价值的文章主要介绍了「二分搜索Binary Search」。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0 框架

int binarySearch(vector<int> &nums, int target)
{
	int left = 0, right = ....;//right具体看情况
	while (....)
	{
		int mid = left + (right - left) / 2;//防止溢出
		if (nums[mid] == target)
		{
			....
		}
		else if (nums[mid] < target)
		{
			left = ....
		}
		else if (nums[mid] <target)
		{
			right = ....
		}
	}
	return ....;
}

二分搜索其实也是双指针,左右指针。

1 基本二分

1.1 寻找一个数

「二分搜索Binary Search」,算法,算法,数据结构,排序算法

题解

直接二分搜索解决。

Code

int binarySearch(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)
		{
			return mid;
		}
		else if (nums[mid] < target)
			left = mid + 1;//注意
		else if (nums[mid] > target)
			right = mid - 1;//注意
	}
	return -1;
}

但是这个数有缺陷,假如有重复的数,例如[1,2,2,2,3],想要找左边界的2,应该返回索引为1,;或者右边界的2,返回索引3,但是发现找不了,只会给你返回中间的2,返回索引2,改进在下边。

结果

「二分搜索Binary Search」,算法,算法,数据结构,排序算法

1.2 寻找左侧边界的二分搜索

Code

int left_bound(vector<int> nums, int target)
{
	if (nums.size() == 0) return -1;
	int left = 0;
	int right = nums.size();//注意,此处搜索区间其实是个左闭右开,因为nums.size()是越界了,索引的最后一个其实是要减去1的

	while (left < right)
	{
		int mid = left + (right - left) / 2;
		if (nums[mid] == target) right = mid;//搜索区间向左侧收缩,排除右边区间了,所以当发现nums[mid] == target的时候,不要直接返回,而是right = mid,再找左边界的,看左边界有没有值,实在不行,没找到,就返回mid了
		else if (nums[mid] < target) left = mid + 1;//左闭右开的区间,[mid + 1, right),排除mid这个点了,因为mid已经搜索过了
		else if (nums[mid] > target) right = mid;//因为是左闭右开的开区间,因为要排除mid,直接等于mid即可[left, mid),这样开区间就取不到mid了
	}
	if (left == nums.size()) return -1;
	return nums[left] == target ? left : -1;//返回left,right都可以
}

注意此处while符号变更了,改成小于号了<。那么为啥用<呢,因为首先搜索区间要包含数组的所有元素,其次,该怎么跳出while循环,当搜索区间没有元素的时候结束,那么搜索区间什么时候没有元素呢?当left = right的时候没有元素,所以这里是小于号<。

若要搜索区间变为左闭右闭的搜索区间,则稍微修改一下。

int left_bound(vector<int> nums, int target)
{
	int left = 0, 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 if (nums[mid] > target)
			right = mid - 1;//注意
	}
	// 判断 target 是否存在于 nums 中
    // 此时 target 比所有数都大,返回 -1
    if (left == nums.length) return -1;
    // 判断一下 nums[left] 是不是 target
    return nums[left] == target ? left : -1;
}

1.3 寻找右侧边界的二分搜索

Code

int right_bound(vector<int> nums, int target) {
    int left = 0, right = nums.size(); //采用左闭右开表示
    
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            left = mid + 1; // 向右边进行收缩
        } else if (nums[mid] < target) {
            left = mid + 1;//左闭右开踢mid,左边[mid + 1, right)
        } else if (nums[mid] > target) {
            right = mid;//左闭右开踢mid,[left, mid)
        }
    }
    // 判断 target 是否存在于 nums 中
	// 此时 left - 1 索引越界
	if (left - 1 < 0) return -1;
	// 判断一下 nums[left] 是不是 target
	return nums[left - 1] == target ? (left - 1) : -1;// 因为最后left = mid + 1了,所以得减去1
}

改成左闭右闭的情况。文章来源地址https://www.toymoban.com/news/detail-610904.html

int right_bound(vector<int> nums, int target) {
    int left = 0, right = nums.size() - 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;
        }
    }
    // 最后改成返回 left - 1
    if (left - 1 < 0) return -1;
    return nums[left - 1] == target ? (left - 1) : -1;
}

到了这里,关于「二分搜索Binary Search」的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 浙大数据结构第四周之04-树6 Complete Binary Search Tree

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with keys less than the node\\\'s key. The right subtree of a node contains only nodes with keys greater than or equal to the node\\\'s key. Both the left and right subtrees must also be binary search trees. A Comple

    2024年02月16日
    浏览(50)
  • 数据结构——用Java实现二分搜索树

    目录 一、树 二、二分搜索树 1.二叉树 2.二分搜索树 三、代码实现 1.树的构建 2.获取树中结点的个数 3.添加元素 4.查找元素 (1)查找元素是否存在 (2)查找最小元素 (3)查找最大元素 5.二分搜索树的遍历 (1)前序遍历: (2)中序遍历: (3)后序遍历: (4)层序遍历

    2024年02月19日
    浏览(42)
  • 二分搜索树(校招数据结构最低要求版)Java

    二分搜索树(Binary Search Tree,BST)是一种常见的数据结构,它能够高效地存储和查找数据。它的特点是每个节点都包含一个值,并且每个节点的左子树的值都小于节点的值,右子树的值都大于节点的值。 通过这种有序的排列方式,我们可以在二分搜索树中进行高效的查找操作

    2024年02月10日
    浏览(45)
  • 数据结构与算法 | 二叉树(Binary Tree)

    二叉树(Binary Tree)是一种树形数据结构,由节点构成,每个节点最多有两个子节点:一个左子节点和一个右子节点。 \\\"二叉树\\\"(Binary Tree)这个名称的由来是因为二叉树的每个节点最多有两个子节点,一个左子节点和一个右子节点。其中,“二叉”指的是两个,因此“二叉树

    2024年02月08日
    浏览(41)
  • 【数据结构与算法】查找(Search)【详解】

    【知识框架】 查找(Searching) :就是根据给定的某个值,在查找表中确定一个其等于给定值的数据元素( 或记录)。 查找表(Search Table) :是由同一类型的数据元素(或记录)构成的集合。 (Key):数据元素中唯一标识该元素的某个数据项的值,使用基于的查找,查

    2024年02月02日
    浏览(49)
  • 数据结构,查找算法(二分,分块,哈希)

    一、查找算法         1、二分查找:(前提条件: 必须有序的序列) 2、分块查找:(块间有序,块内无序)     索引表  +  源数据表     思路:     (1)先在索引表中确定在哪一块中     (2)再遍历这一块进行查找 //索引表 typedef  struct  {     int max; //块中最大值

    2024年02月11日
    浏览(60)
  • Python数据结构与算法篇(五)-- 二分查找与二分答案

    1.1 定义         二分查找又称折半查找、二分搜索、折半搜索等,是一种在静态查找表中查找特定元素的算法。         所谓静态查找表,即只能对表内的元素做查找和读取操作,不允许插入或删除元素。         使用二分查找算法,必须保证查找表中存放的是有

    2023年04月20日
    浏览(48)
  • 数据结构算法--1 顺序查找二分查找

    顺序查找时间复杂度为O(n) 我们可以借助Python中的函数enumerate,通过enumerate遍历列表返回其索引和值 也可以通过列表长度依次遍历: 但是二分查找时间复杂度为O(logn):

    2024年02月12日
    浏览(54)
  • Java数据结构与算法:查找算法之二分查找

    大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,欢迎回到本专栏。在这个冰冷的季节里,我们将一同探讨Java中一种高效的查找算法——二分查找。让我们点燃知识的火花,一同解锁这个查找奇迹的秘密! 二分查找简介 二分查找,也称为折半查找,

    2024年01月21日
    浏览(47)
  • 数据结构和算法之二分法查找

    二分法查找,也称作 二分查找 或 折半查找 ,是一种在有序数组中快速查找特定元素的算法。它采用分治法思想,通过将问题划分为规模更小的子问题,并且通过对子问题的查找来解决原问题。 二分法查找的思路是不断地将数组一分为二,然后判断目标值在哪一部分,进而

    2024年02月09日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包