【数据结构】二分查找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;

}

}

相关推荐
灰灰勇闯IT5 分钟前
ops-reduce:ReduceMax 与 ReduceMean 的并行优化
算法
笨拙的老猴子11 分钟前
[特殊字符] Java GC机制详解:G1、ZGC、Shenandoah全面解析与版本演进对比
java·开发语言
水木流年追梦14 分钟前
大模型入门-Reward 奖励模型训练
开发语言·python·算法·leetcode·正则表达式
JavaWeb学起来14 分钟前
Python学习教程(六)数据结构List(列表)
数据结构·python·python基础·python教程
沙威玛_LHE24 分钟前
P13376题解
算法
枕星而眠36 分钟前
Linux 四大进程/线程同步锁详解:互斥锁、读写锁、条件变量、文件锁
linux·c语言·后端·ubuntu·学习方法
砍材农夫42 分钟前
物联网 基于netty构建mqtt协议规范(遗嘱与保留消息)
java·开发语言·物联网·netty
DFT计算杂谈1 小时前
KPROJ编译教程
java·前端·python·算法·conda
重生之我是Java开发战士1 小时前
【笔试强训】Week5:空调遥控, kotor和气球,走迷宫,主持人调度II,体操队形,二叉树的最大路径和,排序子序列,消减整数
java·算法·动态规划
郑重其事,鹏程万里1 小时前
表达式计算器(mvel2)
java