yzzheng

V1

2023/02/08阅读:19主题:红绯

剑指offer(一)

二分搜索

剑指 Offer 04. 二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右 非递减 的顺序排序,每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

输入案例
输入案例

【解法1】二分查找 轮着每行查

【解法2】直接查找 从矩阵的左下角看,上方的数字都比其小,右方的数字都比其大,所以依据该规律去判断数字是否存在 设当前数字为 cur,目标数字为 target,当 target < cur 时,cur 更新为其上面的数字,当 target > cur 时,cur 更新为其右侧的数字,直到相等则返回 true,否则到了矩阵边界返回 false 时间复杂度:

public boolean findNumberIn2DArray(int[][] M, int target) {
    int n = M.length;
    if(n == 0return false;
    int m = M[0].length;
    int i = n-1, j = 0;
    while(0 <= i && i < n && 0 <= j && j < m){
        if(M[i][j] == target) return true;
        else if(M[i][j] > target) i--;
        else j++;
    }
    return false;  
}

剑指 Offer 11. 旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

输入案例
输入案例

题目是用二分法,case有三种情况

3种情况
3种情况

如上图所示,输入的情况跟右端点比较。如果数组中的元素都一样则right--,因为数组是升序的,所以最小值一定靠近左侧,而不是右侧

public int minArray(int[] numbers) {
    int n = numbers.length;
    int left = 0, right = n-1;
    while(left <= right){
        int mid = (left + right) >> 1;
        if(numbers[mid] < numbers[right]){
            right = mid;
        }else if(numbers[mid] > numbers[right]){
            left = mid + 1;
        }else{
            right--;
        }
    }
    return numbers[left];
}

分类:

后端

标签:

数据结构与算法

作者介绍

yzzheng
V1

hello