力扣Leetcode热题100-二分查找 解题思路分享

1.搜索插入位置

题目如下:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

思路分析

与最基本的二分查找算法类似,但是基础的二分查找在找不到值的时候一般情况下返回 -1 ,找到的值返回索引,下面先展示最基本的二分查找的Java代码:

 public static int binarySearch(int[] arr,int target){
        int i = 0; //设置位于索引 0 位置的指针
        int j = arr.length - 1; //设置位于最后一位索引位置的指针
        while(i <= j){   //继续循环的条件
            int m = (i + j)>>1; //设置位于数组中间位置的指针
            if(arr[m] > target){  //情况一:目标值在中间值的左边
                j = m - 1;  //移动末位置指针,缩小检索范围
            } else if (arr[m] < target) { //情况二:目标值在中间值的右边
                i = m + 1;  //移动 0 位置指针,缩小检索范围
            }else {   //arr[m] == target的情况
                return m;  //找到目标索引
            }
        }
        return -1; //没找到target
    }

这是最基础的二分查找代码,有助于我们解答接下来的其它题目。

我们接着看这道题,想要处理寻找插入值位置的操作,首先我们会先把 中间值等于目标值的情况合并到 目标值在中间值的左边的情况里面,然后删除没找到目标值就返回 -1 的语句,因为我们在一个升序的数组当中,寻找一个不存在的目标值,最基础的二分查找m指针不可能指向 目标值 而是最终的m指针的右边一位(可自己列一串数组验证)。

代码演示

 public static int binarySort(int[] arr, int target) {
        int i = 0;
        int j = arr.length - 1;
        while (i <= j) {
            int m = (i + j) >> 1; //右移运算,可提高计算效率
            if (arr[m] >= target) {
                j = m - 1;
            } else {
                i = m + 1;
            }
        }
        return i;
    }

2.搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵:

  • 每行中的整数从左到右按非递减顺序排列。

  • 每行的第一个整数大于前一行的最后一个整数。

给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false

思路分析

看到这道题目,最直接的思路就是把二维数组直接存入一个一维数组当中再进行二分查找,这个方法的可行性主要是基于这两个条件:

  • 每行中的整数从左到右按非递减顺序排列。

  • 每行的第一个整数大于前一行的最后一个整数。

这使得我们最后合并的数组一定是一个升序的数组。那么接下来的问题就转化为如何把二维数组存入一维数组的问题,这就很简单了,遍历二维数组元素存入即可。

代码演示

首先我们先完成将二维数组存入一维数组的代码部分:

 private static int[] changeArr(int[][] matrix){
        int[] newArr = new int[matrix.length * matrix[0].length];//创建新数组
        int index = 0; //作为新数组的索引,接下来每次遍历 +1 即可
        for (int i = 0; i < matrix.length; i++) {     //外循环
            for (int j = 0; j < matrix[i].length; j++) {  //内循环
                newArr[index] = matrix[i][j];
                index++;
            }
        }
        return newArr;
    }

然后就是正常的二分查找部分,二分查找代码部分就不演示了

最后演示完整的代码:

 public static boolean searchMatrix(int[][] matrix, int target) {
        int[] ints = changeArr(matrix);
        int i = binarySearch(ints, target);
        if (i == -1) {       //没找到target
            return false;
        } else {            //找到target
            return true;
        }
    }

    private static int[] changeArr(int[][] matrix) {
        int[] newArr = new int[matrix.length * matrix[0].length];//创建新数组
        int index = 0; //作为新数组的索引,接下来每次遍历 +1 即可
        for (int i = 0; i < matrix.length; i++) {     //外循环
            

你可能感兴趣的:(Leetcode,热门100,leetcode,职场和发展,java,开发语言)