首页 > 编程语言 >算法与数据结构——二分查找插入点

算法与数据结构——二分查找插入点

时间:2024-09-12 13:51:45浏览次数:1  
标签:二分 target nums 元素 插入 查找 数据结构

二分查找插入点

二分查找不仅可用于搜索目标元素,还可以解决许多变种问题,比如搜索目标元素的插入位置。

无重复元素情况

Question
给定一个长度为n的有序数组nums和一个元素target,数组不存在重复元素。现将target插入数组nums中,并保持其有序性。若数组中已存在元素target,则插入到其左方。请返回插入后target在数组中的索引。

问题一:当数组中包含target时,插入点的索引是否就是该元素的索引?

题目要求将target插入到相等元素的左边,这意味着插入的target替换了原来target的位置。也就是说,当数组包含target时,插入点的索引就是该target的索引

问题二:当数组中不存在target时,插入点是哪个元素的索引?

进一步思考二分查找过程(m为中点索引):当nums[m] < target时,这意味着指针i在向大于等于target的元素靠近。同理,指针j始终在向小于等于target的元素靠近。
因此二分结束时一定有:i指向首个大于target的元素,j指向首个小于target的元素。易得当数组不包含target时,插入索引为i

代码示例如下:

/*二分查找插入点(无重复元素)*/
int binarySearchInsertionSimple(vector<int> &nums, int target){
	int i = 0, j = nums.size() - 1;
	while (i <= j){
		int m = i + (j - i) / 2;
		if (nums[m] < target)
			i = m + 1;
		else if (nums[m] > target)
			j = m - 1;
		else
			return m;  // 找到target 返回插入点 m
	}
	return i;			// 未找到 target,返回插入点 i
}

存在重复元素的情况

假设数组中存在多个target,则普通二分查找只能返回其中一个target的索引,而无法确定该元素的左边和右边还有多少个target

题目要求将目标元素插入到最左边,所以我们需要查找数组中最左一个target的索引

实现步骤:

  1. 执行二分查找,得到任意一个target索引,记为k。
  2. 从索引k开始,向左进行线性遍历,当找到最左边的target时返回。

此方法虽然可用,但其包含线性查找,因此时间复杂度为O(n)。当数组中存在很多重复的target时,该方法效率很低。

现考虑拓展二分查找代码。如图所示,整体流程保持不变,每轮现计算中点索引m,再判断targetnums[m]的大小关系,分以下几种情况:

  • nums[m] < targetnums[m] > target时,说明还没有找到target,因此采用普通二分查找的缩小区间操作,从而使指针i和j向target靠近
  • nums[m] == target时,说明小于target的元素在区间[i,m-1]中,因此采用j = m-1来缩小区间,从而使指针j向小于target的元素靠近

循环完成后,i指向最左边的target,j指向首个小于target的元素,因此索引i就是插入点








观察以下代码,其中判断分支nums[m] > targetnums[m] == target的操作相同,因此两者可以合并。即便如此,我们仍然可以将判断条件保持展开,因为逻辑更加清晰、可读性更好。

/*二分查找插入点(存在重复元素)*/
int binarySearchInsertion(vector<int> &nums, int target){
	int i = 0, j = nums.size() - 1;
	while (i <= j){
		int m = i + (j - 1) / 2;
		if (nums[m] < target)
			i = m + 1;		// target 在区间 [m+1, j] 中
		else if (nums[m] > target)
			j = m - 1;		// target 在区间 [i, m-1] 中
		else
			j = m - 1;		// 首个小于 target 的元素在区间 [i, m-1] 中
	}
	// 返回插入点
	return i;
}

总的看来,二分查找无非就是给指针i和j分别设定搜索目标,目标可能是一个具体元素(例如target),也可能是一个元素范围(如小于target的元素)。

在不断的循环二分中,指针i和j都逐渐逼近预先设定的目标。

标签:二分,target,nums,元素,插入,查找,数据结构
From: https://www.cnblogs.com/1873cy/p/18409659

相关文章

  • Java-数据结构-二叉树-基础 (o゚▽゚)o
    文本目录:❄️一、树形结构:  ▶ 1、概念:▶ 2、特殊的概念: ▶ 3、树的表示形式:❄️二、二叉树:  ▶ 1、概念:   ▶2、两种特殊的二叉树:     ➷1)、满二叉树:      ➷ 2)、完全二叉树:  ▶3、二叉树的性质:    ➷ 1)性质一:  ......
  • 线段树与二分操作 vases and flowers ——hdu 4614
    操作1,的关键是找到第一只和最后一只空花瓶,完全可以利用二分法查找,找第一只花瓶可以在[X,N]内查找,第一个位置pos1,最后一只花瓶则在[POS1,N]中找,然后更新[POS1,POS2],全部置1即可代码:#include<iostream>usingnamespacestd;constintN=5e4+5;structnode{ intlazy; in......
  • 算法与数据结构——二分查找
    二分查找二分查找(binarysearch)是一种基于分治策略的高效搜索算法。它利用数据的有序性,每轮缩小一半搜索范围,直至找到目标元素或搜索区间为空为止。Qustion:给定一个长度为n的数组nums,元素按从小到大的顺序排列且不重复。请查找并返回元素target在该数组中的索引。若数组不包含......
  • python根据关键字查找文件所在路径位置
    importosimportfnmatchdeffind_files(directory,keyword):"""在给定目录及其子目录中查找包含关键词的文件"""forroot,dirs,filesinos.walk(directory):forbasenameinfiles:ifkeywordinbasename:......
  • 二分
    二分答案要对一个有单调性的区间二分查找:|可行||不可行|,即某个点的一个方向全可行,另一个方向全不可行,要找这个点。(大部分时候求谁就二分谁,但也有例外,例外:http://noip.ybtoj.com.cn/contest/868/problem/8)更概括的,一段区间被一个点分成两种状态或特性经典题型最大值最小/最小......
  • 56.《数据结构-线性表白话看》
    知识参考王道考研硬看知识和视频一直瞌睡无聊破了两天题才寻得规律故在此记录分为顺序存储和链式存储线性表的定义:具有相同数据类型的n个数据元素的有限序列注意相同数据类型有限序列还有就是线性表是一种逻辑结构顺序表和链表是存储(物理)结构1.顺序存储即顺序表......
  • 数据结构:线性表的顺序表实现
    顺序表的操作:这里采用了结构体和指针的部分知识//自定义结构体typedefstruct{ DataTypelist[Maxsize]; intsize;}SeqList;voidListInitiate(SeqList*L){ L->size=0;}intListLength(SeqListL){ returnL.size;}//插入是从前往后移动intListInsert(Seq......
  • LeetCode 704.二分查找 (java)
    给定一个 n 个元素有序的(升序)整型数组 nums和一个目标值 target ,写一个函数搜索 nums 中的target,如果目标值存在返回下标,否则返回-1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在nums中并且下标为4示例 2:......
  • 算法与数据结构——图的基础操作及图的遍历(广度优先与深度优先)
    图的实现基于邻接矩阵的实现给定一个顶点数量为n的无向图:初始化:传入n个顶点,初始化长度为n的顶点列表vertices,使用O(n)时间;初始化n*n大小的邻接矩阵adjMat,使用O(n2)时间。添加或删除边:直接在邻接矩阵中修改指定的边即可,使用O(1)时间。而由于是无向图,因此需要同时更新两个......
  • OpenCV结构分析与形状描述符(19)查找二维点集的最小面积外接旋转矩形函数minAreaRect()
    操作系统:ubuntu22.04OpenCV版本:OpenCV4.9IDE:VisualStudioCode编程语言:C++11算法描述找到一个包围输入的二维点集的最小面积旋转矩形。该函数计算并返回指定点集的最小面积边界矩形(可能是旋转的)。开发者需要注意的是,当数据接近包含的Mat元素边界时,返回的Rotated......