二分搜索

Posted 爱coding的卖油翁

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分搜索相关的知识,希望对你有一定的参考价值。

查找搜索在我们平时的开发中,用到的还是挺多的,所以对于一般的搜索算法,我们也是需要了解一下的。


问题:查找指定元素的位置

    public int binarySearch(int[] array, int target)  // O(Log2N) O(1)
        if (array == null || array.length == 0) return -1;
        int left = 0;
        int right = array.length - 1;
        while (left <= right) 
            int mid = left + (right - left) / 2; // integer may out of bound
            if (array[mid] < target) 
                left = mid + 1;
             else if (array[mid] > target) 
                right = mid - 1;
             else 
                return mid;
            
        
        return -1;
    

上面这段代码就是二分查找算法,终结条件就是 left > right,这是二分查找的核心。
时间复杂度 O(log2N)
空间复杂度 O(1)


问题:查找第一个出现的元素

描述:给定一个目标整数 T 和一个按升序排序的整数数组,如果找到整数 T 第一次出现的位置,就返回该位置索引,否则,返回-1。

例子:
A = 1,2,3 T = 2,return 1
A = 1,2,3 T = 4,return -1
A = 1,2,2,2,2,3 T = 2,return 1

    public int findFirst(int[] array, int target)  // O(Log2N) O(1)
        if (array == null || array.length == 0) return -1;
        int left = 0;
        int right = array.length - 1;
        while (left < right - 1) 
            int mid = left + (right - left) / 2;
            if (array[mid] < target) 
                left = mid;
             else if (array[mid] >= target) 
                right = mid;
            
        

        // post processing
        if (array[left] == target) return left;
        if (array[right] == target) return right;

        return -1;
    

时间复杂度 O(log2N)
空间复杂度 O(1)


问题:查找指定元素的位置

描述:给定一个目标整数 T 和一个按升序排序的整数数组,找出 T 在数组中最接近 T 的元素的索引。

例子:
A = 1,2,3 T = 2,return 1
A = 1,4,6 T = 3,return 1
A = 1,4,6 T = 5,return 1 or 2
A = 1,3,3,4 T = 2,return 0 or 1 or 2

    public int findClosest(int[] array, int target)  // O(Log2N) O(1)
        if (array == null || array.length == 0) return -1;
        int left = 0;
        int right = array.length - 1;
        while (left < right - 1) 
            int mid = left + (right - left) / 2;
            if (array[mid] == target) 
                return mid;
             else if (array[mid] > target) 
                right = mid;
             else 
                left = mid;
            
        
        // post processing
        if ( Math.abs( target - array[left] ) <= Math.abs( target - array[right] ) ) 
            return left;
         else 
            return right;
        
    

问题:查找指定元素的位置

/**
 * array: m * n
 * time: log(number of elements) -log(m * n)
 * space:O(1)
 */
public class SearchMatrix 

    public static void main(String[] args) 
        int[][] matrix = 
                1, 2, 3,
                4, 5, 6,
                7, 8, 9,
                10, 11, 12
        ;
        int[] index = new SearchMatrix().searchMatrix(matrix, 7);
        System.out.println("index:" + index[0] + " " + index[1]);
    

    public int[] searchMatrix(int[][] matrix, int target)  // O(Log2 M x N) O(1)
        int[] res = -1, -1;
        int num_row = matrix.length;
        int num_col = matrix[0].length;
        int left = 0;
        int right = num_row * num_col - 1;
        while (left <= right) 
            int mid = left + (right - left) / 2;
            if (target == matrix[mid / num_col][mid % num_col]) 
                res[0] = mid / num_col;
                res[1] = mid % num_col;
                return res;
             else if (matrix[mid / num_col][mid % num_col] > target) 
                right = mid - 1;
             else 
                left = mid + 1;
            
        
        return res;
    


以上是关于二分搜索的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode74. 搜索二维矩阵

力扣刷题笔记 1《二分查找》

[算法模板]二分查找

LeetCode每日一题:240搜索二维矩阵II

二分查找

Leetcode之二分法专题-240. 搜索二维矩阵 II(Search a 2D Matrix II)