【数据结构】二分查找5.12

Basic

需求:在有序数组A内,查找值target

如果找到返回索引

如果找不到返回-1


算法描述

前提:给定一个内含n个元素的有序数组A(升序),一个待查找值

设置两个索引:i=0;j=n-1;

如果j>i,查找停止

设置m=floor(i+j/2),floor为向下取整的最小整数

如果target>m,设置i=m+1;

如果traget<m,设置j=m-1;

如果traget=m,找到待查找值。

实现

java 复制代码
package 二分查找;

public class BinarySearch {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}
     public static int binarySearchBasic(int[] a,int target) {
    	 int i=0,j=a.length-1; //设置指针初值
    	 while(i<=j) { //范围有内容
    		 int m=(i+j)/2;
    		 if(target<a[m]) {
    			 j=m-1;
    		 }else if(target>a[m]) {
    			 i=m+1;
    		 }else {
    			 return m;
    		 }
    	 }
    	 return -1;
	}

}

问题1:

为什么是i<=j,而不是i<j?

i,j区间内会有未比较的元素,i<=j它们共同指向的元素也可以遍历到。

问题2:

(i+j)/2有没有问题?

若数字较大,再次循环:

i=m+1;

m=(i+j)/2;会超出范围变成负数

同一个二进制数,第一位是否是符号位。会使数值展现不同。(Java中会考虑符号位)

可以通过无符号右移来达到除2效果。

解决方法:

无符号右移>>>

java 复制代码
package 二分查找;

public class BinarySearch {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}
     public static int binarySearchBasic(int[] a,int target) {
    	 int i=0,j=a.length-1; //设置指针初值
    	 while(i<=j) { //范围有内容
    		 int m=(i+j)>>>2;
    		 if(target<a[m]) {
    			 j=m-1;
    		 }else if(target>a[m]) {
    			 i=m+1;
    		 }else {
    			 return m;
    		 }
    	 }
    	 return -1;
	}

}

额外应用:

(0+7)/2 3.5 //不需要设置float,可当成整数

(0+7)>>>1 3

练习优化过程

Pocess1超出时间限制

class Solution {

public int searchInsert(int\[\] nums, int target) {

int i=0,j=nums.length-1;

int m=(i+j)>>>1;

int index=0;

while(i<=j){

index++;

if(target<m){

j=m-1;

}else if(m<target){

i=m+1;

}else{

return index;

}

}

for(int k=0;k<nums.length;k++){

while(target>numsk){

index=k+1;

}

}

return index;

}

}

问题分析:

  1. 二分查找逻辑错误:比较 target 和 m(中间索引)而不是 numsm(中间值)。

  2. 无限循环:在二分查找部分,没有更新 m的值,导致循环条件永远不变。

  3. 错误的索引计算:在二分查找中返回的是 index(循环次数)而不是正确的位置。

  4. 不必要的线性搜索:最后的线性搜索部分既不正确也不必要。i就是应该插入的位置。

Process2优化

class Solution {

public int searchInsert(int\[\] nums, int target) {

int i = 0, j = nums.length - 1;

while (i <= j) {

int m = (i + j) >>> 1;

if (numsm == target) {

return m;

} else if (numsm < target) {

i = m + 1;

} else {

j = m - 1;

}

return i;

}

}

相关推荐
lulu12165440782 分钟前
OpenRouter Fusion 多模型融合架构深度拆解:预算级模型组团打平 Fable 5,多模型协作才是 AGI 的正确打开方式?
java·人工智能·架构·ai编程·agi
雨辰AI7 分钟前
生产级实测:SpringBoot3 + 达梦数据库接口从 200ms 优化至 20ms 完整调优指南
java·数据库·spring boot·后端·政务
林间码客18 分钟前
04 ROC曲线与AUC:从零开始手动计算
大数据·人工智能·算法
Irissgwe22 分钟前
map/set/multimap/multiset 的底层逻辑与实现
数据结构·c++·算法·二叉树·stl·c·红黑树
IronMurphy26 分钟前
【算法五十八】23. 合并 K 个升序链表
数据结构·算法·链表
思茂信息32 分钟前
CST软件基于液态金属开关的方向图可重构天线
服务器·算法·重构·cst·仿真软件·电磁仿真
(Charon)36 分钟前
【C++ 面试高频:内存管理、RAII 和智能指针详解】
java·开发语言·word
凡人叶枫1 小时前
Effective C++ 条款39:明智而审慎地使用 private 继承
java·数据库·c++·嵌入式开发
月疯1 小时前
PPG研究中暑的算法记录
算法
春日见1 小时前
vscode的AI编程插件推荐:
大数据·ide·vscode·算法·机器学习·编辑器·ai编程