14. 二分查找

ⅰ亾dé卋堺 提交于 2019-12-02 15:09:05

给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1。

样例

样例 1:

输入:[1,4,4,5,7,7,8,9,9,10],1

输出: 0

样例解释:

第一次出现在第0个位置。

 

样例 2:

输入: [1, 2, 3, 3, 4, 5, 10],3

输出: 2

样例解释:

第一次出现在第2个位置

样例 3:

输入: [1, 2, 3, 3, 4, 5, 10],6

输出: -1

样例解释:

没有出现过6, 返回-1

挑战

如果数组中的整数个数超过了2^32,你的算法是否会出错?

我自己写的

public class Solution {
    /**
     * @param nums: The integer array.
     * @param target: Target to find.
     * @return: The first position of target. Position starts from 0.
     */
    public int binarySearch(int[] nums, int target) {
        // write your code here
        int ret = -1;
        int start = 0;
        int end = nums.length;
        int flag = nums.length / 2;
        while (true) {
            if (nums[flag] == target) {
                if (flag == 0 || nums[flag] > nums[flag - 1]) {
                    return flag;
                } else {
                    flag--;
                }
            } else if (nums[flag] > target) {
                end = flag;
                flag = flag / 2;
            } else {
                start = flag;
                flag = flag + (end - flag) / 2;
               
            }

            if (start == flag) {
                if (nums[flag] == target) return flag;
                if (nums[end] == target) return flag;
                break;
            }else if (end == flag) {
                if (nums[flag] == target) return flag;
                if (nums[start] == target) return flag;
                break;
            }
        }
        return ret;
    }
}

别人的写法

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



//标准的写法
public class Solution {
    /**
     * @param A: an integer sorted array
     * @param target: an integer to be inserted
     * @return: An integer
     */
    public int searchInsert(int[] array, int value) {
        // write your code here
        int lo = 0;
        int hi = array.length - 1;
        while (lo <= hi) {
            final int mid = (lo + hi) >>> 1;
            final int midVal = array[mid];

            if (midVal < value) {
                lo = mid + 1;
            } else if (midVal > value) {
                hi = mid - 1;
            } else {
                return mid;  // 找到了
            }
        }
        return lo;  // 没找到
    }
}

 递归

    /**
     * 使用递归的二分查找
     *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;
        }    
        
    }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!