【数据结构】二分查找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>nums[k]){

index=k+1;

}

}

return index;

}

}

问题分析:

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

  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 (nums[m] == target) {

return m;

} else if (nums[m] < target) {

i = m + 1;

} else {

j = m - 1;

}

return i;

}

}

相关推荐
flashlight_hi3 分钟前
LeetCode 分类刷题:110. 平衡二叉树
javascript·算法·leetcode
式5164 分钟前
线性代数(九)线性相关性、基与维数
线性代数·算法·机器学习
小徐Chao努力4 分钟前
Spring AI Alibaba A2A 使用指南
java·人工智能·spring boot·spring·spring cloud·agent·a2a
啊阿狸不会拉杆5 分钟前
《数字图像处理》第7章:小波变换和其他图像变换
图像处理·人工智能·python·算法·机器学习·计算机视觉·数字图像处理
炽烈小老头5 分钟前
【 每天学习一点算法 2025/12/17】验证二叉搜索树
学习·算法
用户2719953721312 分钟前
基于Label Studio 集成视觉大模型Qwen2-VL和yolo实现自动标注
算法
rannn_11114 分钟前
【Git教程】概述、常用命令、Git-IDEA集成
java·git·后端·intellij-idea
我家领养了个白胖胖14 分钟前
向量化和向量数据库redisstack使用
java·后端·ai编程
苹果醋325 分钟前
Java设计模式实战:从面向对象原则到架构设计的最佳实践
java·运维·spring boot·mysql·nginx
智者知已应修善业33 分钟前
【删除有序数组中的重复项 II之O(N)算法】2024-1-31
c语言·c++·经验分享·笔记·算法