IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二分法 java -> 正文阅读

[数据结构与算法]二分法 java


以下假设数组递增。

普通二分

目标:从数组中寻找target,有则返回下标,没有则返回-1。

返回值范围:[-1, n-1]

终止while条件:如果不包含target,即正常退出while,则此时必有left=right+1。此时区间[left,right]不包含任何元素,返回-1。

区间缩小规则:

  1. 如果mid==target,返回mid。
  2. 如果mid>target,在[left, mid-1]找,
  3. 否则,在[mid+1,right]找。

特点:如果有多个元素=target,会返回任意一个。

public static int binarySearch(int[] arr, int target){
	int left = 0;
	int right = arr.length-1;
	while(left<=right){// 注意
	    int mid = (left+right)/2;
	    if(arr[mid]==target){
	        return mid;
	    }else if(arr[mid] >target){
	        right = mid-1;
		    }else if(arr[mid]<target){
        	left = mid+1;
    	}
	}
	return -1;
}

为什么right初始值是arr.length-1,终止while前有left=right,进而mid=right,如果right=arr.length,会越界。而且根据返回值的意义和范围,left和right需要设置成这样。

找第一个大于等于target的下标

目标:找第一个大于等于target的下标;
返回值还有一个含义:小于target的数有几个。
具体来说,如果数组里面有target,返回第一次等于target的元素下标:如果不包含target,则返回第一个大于target 的元素下标。若所有元素均小于target,返回n。

返回值范围:[0,n]

终止while条件:必有left==right。此时区间[left,right]里只有一个元素,直接返回left或right

区间缩小方法:

  1. 如果mid元素大于等于target。要找的必定是当前位置或者当前位置左边,令right=mid,即在[left,mid]之间找。
  2. 如果mid元素小于target,要找的下标必定在右边:left = mid+1,即在[mid+1, right]之间找。
// 只有4个需要注意的地方。
public static int binarySearch(int arr[], int target){
    int left = 0;
    int right = arr.length; // 注意
    while(left<right){ // 注意
        int mid = (left+right)/2;
        if(arr[mid] >= target){// 注意
            right = mid;
        }else{
            left = mid+1;
        }
    }
    return left;// 注意
}

为什么right初始值是arr.length。因为终止while前必有left<right,进而mid<right,所以不用担心越界。而且根据返回值的意义和范围,left和right需要设置成这样。

找第一个大于target的下标

目标:找第一个大于target的下标;没有大于target的元素则返回n
返回值还有一个含义:小于等于target的数有几个。

返回值范围:[0, n]

终止while条件:必有left==right。此时区间[left,right]里只有一个元素,直接返回left或right

区间缩小方法:

  1. 如果mid元素大于target。要找的必定是当前位置或当前位置左边,right=mid,即在[left,mid]之间找。
  2. 如果mid元素小于等于target,要找的下标必定在右边:left = mid+1,即在[mid+1, right]之间找。
public static int binarySearch(int arr[], int target){
    int left = 0;
    int right = arr.length;
    while(left<right){
        int mid = (left+right)/2;
        if(arr[mid] > target){// 注意
            right = mid; 
        }else{
            left = mid+1;
        }
    }
    return left;// 注意
}

找最后一个小于等于target的下标

作用:找出最后一个小于等于target的元素下标。所有元素均大于target则返回-1.

返回值范围:[-1,n-1]

分析:用上面的方法可以找第一个大于target的下标index,因此index-1对应的元素必定不大于target,index-1即为所求。
所以只需要把上面的代码最后一行改成left-1就可以了。

public static int binarySearch(int arr[], int target){
    int left = 0;
    int right = arr.length;
    while(left<right){
        int mid = (left+right)/2;
        if(arr[mid] > target){// 注意
            right = mid; 
        }else{
            left = mid+1;
        }
    }
    return left-1;// 注意
}

找target第一次/最后一次出现的位置

上面可以找出第一个大于等于target的下标index。如果index对应元素等于target,则index则为所求。否则说明不包含target。

同理,上面可以找出最后一个小于等于target的下标index。如果index对应元素等于target,则index则为所求。否则说明不包含target。

总结

例子:
原数组: {3,6,6,9,10,11} 长度n=6

方法返回值范围target=0的返回值target=6的返回值target=15的返回值
普通二分[-1,n-1]-12-1
第一个大于等于target[0,n]016
第一个大于target[0,n]036
最后一个小于等于target[-1,n-1]-125

注:很多人说普通二分,其他while里面是left<right,由此说明其搜索区间是左闭右开,但是我觉得仍然应该理解成左闭右闭。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 22:26:28  更:2022-03-11 22:27:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 14:48:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码