二分查找算法

二分查找法题解

	/**
	 * 不使用递归的二分查找
	 *title:binarySearch
	 *@param arr
	 *@param key
	 *@return 关键字位置
	 */
	public static int binarySearch(int[] arr,int key){
		int left = 0;
		int right = arr.length - 1;
		int mid = 0;			//定义middle
		//基于升序
		if(key < arr[left] || key > arr[right] || left > right){
			return -1;				
		}	
		while(left <= right){
			//mid = (left + right) / 2;
            mid = left+(right-left)>>1;
			if(arr[mid] > key){
				//比关键字大则关键字在左区域
				right = mid - 1;
			}else if(arr[mid] < key){
				//比关键字小则关键字在右区域
				left = mid + 1;
			}else{
				return mid;
			}
		}	
		return -1;		//最后仍然没有找到,则返回-1
        
        
  /**
	 * 使用递归的二分查找
	 *title:recursionBinarySearch
	 *@param arr 有序数组
	 *@param key 待查找关键字
	 *@return 找到的位置
	 */
	public static int recursionBinarySearch(int[] arr,int key,int low,int high){
		if(key < arr[low] || key > arr[high] || low > high){
			return -1;				
		}
		int middle = (low + high) / 2;//初始中间位置
		if(arr[middle] > key){
			//比关键字大则关键字在左区域
			return recursionBinarySearch(arr, key, low, middle - 1);
		}else if(arr[middle] < key){
			//比关键字小则关键字在右区域
			return recursionBinarySearch(arr, key, middle + 1, high);
		}else {
			return middle;
		}	
		
	}

旋转数组的最小数字(改造二分法)

在这里插入图片描述

分析:

最小值藏在无序的一边

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wr7UggV4-1645280519493)(JAVA算法竞赛练习电子笔录.assets/image-20211022013046295-163483744756229.png)]

 //旋转数组最小值
    public static int xzsz(int arr[]){
        //二分查找变体
        int begin=0;
        int end=arr.length-1;
        //考虑非旋转数组的情况
        if(arr[begin]<arr[end])return arr[begin];
        //最后剩2个元素
        while(begin+1<end) {
            //中心
            int half = begin + (end - begin) >> 1;
            //找出无序的部分
            //中心的值要小于最后一个元素则说明从中心到最后一个这一段有序
            //等于的不一定情况   如  2 2 2 3    0 1 1 1 这种
            //取arr[half] <= arr[end]的结果System.out.println(xzsz(new int[]{4,4,4,5,3,4})); 结果为4(错误)
            //不取等上面情况是跑不通的
            //对于取等的情况需要顺序扫面法
            if (arr[half] < arr[end]) {//这里说明 half=>end有序 但也存在意外 上面的其他情况
                end = half;
            }
            else{
                begin=half;
            }
        }
        return arr[end];
    }

在有空窜的有序串数组中查找

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8TwRuH3Y-1645280519494)(JAVA算法竞赛练习电子笔录.assets/image-20211022231027435-16349154290441.png)]

除二分查找需掌握的其他知识

//1、“==”比较两个变量本身存储的值,即两个对象在内存中的首地址。
//2、“equals()”比较字符串中所包含的内容是否相同。

“abc”.equals(str) 与str.equals(“abc”):

最后结论:
    "".equals(str)在str为null的时候返回false,
    str.equals("")在str为null时会抛空指针异常.

“”是字符串常量,同时也是一个String类的对象,作为对象可以调用String类里的方法。

null 是空常量,不能调用任何的方法,否则会出现空指针异常,null常量可以给任意的引用数量类型赋值。

//int compareTo(String anotherString)说明:

​ //如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。
​ //如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。
​ // 如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。

 //在有空字符串的有序字符串数组中查找
    public static int find(String []arr,String str){
        //["a","","ab","ac","","ad","b","","ba"]
        //有序数组查找首先想到 二分法
        int begin=0;
        int end=arr.length-1;
        if(str.equals(""))
            return -1;
        while(begin<=end){
            int half=begin+(end-begin)>>1;
            //1、“==”比较两个变量本身存储的值,即两个对象在内存中的首地址。
            //2、“equals()”比较字符串中所包含的内容是否相同。
            //当中心为空串时需要处理:++ 或者-- 来找到一个非空的串
            while(arr[half].equals("")){
                ++half;
                //注意
                if(half>end){
                    return -1;
                }
            }
            //int compareTo(String anotherString)说明:
            //
            //如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。
            //如果第一个字符和参数的第一个字符相等,则以第二个字符和参数的第二个字符做比较,以此类推,直至不等为止,返回该字符的ASCII码差值。
            // 如果两个字符串不一样长,可对应字符又完全一样,则返回两个字符串的长度差值。
            if(arr[half].compareTo(str)>0){// 这里是  half位置的串要大于str
                end=half-1;
            }
            else if(arr[half].compareTo(str)<0){
                begin=half+1;
            }
            else{
                return half;
            }
        }
        return -1;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值