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

}

}

相关推荐
Ricky111zzz6 分钟前
leetcode学python记录1
python·算法·leetcode·职场和发展
汀、人工智能6 分钟前
[特殊字符] 第58课:两个正序数组的中位数
数据结构·算法·数据库架构··数据流·两个正序数组的中位数
liu****7 分钟前
第16届省赛蓝桥杯大赛C/C++大学B组(京津冀)
开发语言·数据结构·c++·算法·蓝桥杯
云烟成雨TD11 分钟前
Spring AI Alibaba 1.x 系列【5】ReactAgent 构建器深度源码解析
java·人工智能·spring
汀、人工智能14 分钟前
[特殊字符] 第79课:分割等和子集
数据结构·算法·数据库架构·位运算·哈希表·分割等和子集
最初的↘那颗心15 分钟前
Agent 实战:构建第一个 Agent 与记忆系统设计
java·大模型·agent·spring ai·记忆系统
程序猿_极客16 分钟前
SpringBoot 三大参数注解详解:@RequestParam @RequestBody @PathVariable 区别及常用开发注解
java·spring boot·后端·面试八股文·springboot注释
小胖java21 分钟前
校园通衢公告枢纽系统
java·spring boot
Crazy________22 分钟前
docker4.8
java·开发语言·eureka
汀、人工智能25 分钟前
[特殊字符] 第74课:完全平方数
数据结构·算法·数据库架构·图论·bfs·完全平方数