4题目描述:

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

示例:

现有矩阵 matrix 如下:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]

给定 target = 5,返回 true。
给定 target = 20,返回 false。

解析:

1.首先矩阵为空或者矩阵的长度为零,则返回false
2.从矩阵matrix右上角元素开始遍历,并与目标值对比,分为三种情况
当matrix[i][j] > target时, 则j--,即消去第j列元素
当matrix[i][j] < target时, 则i++,即消去第i行元素
当matrix[i][j] = target时, 则返回true,代表找到目标值
3.当i或j越界时,则代表矩阵中没有目标值,返回false

Java:

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

JavaScript:

var findNumberIn2DArray = function(matrix, target) {
    if(matrix === null || matrix.length === 0) {
        return false;
    }
    let i = 0, j = matrix[0].length - 1;
    while(i < matrix.length && j >= 0) {
        if(matrix[i][j] > target) {
            j--;
        } else if(matrix[i][j] < target) {
            i++;
        } else {
            return true;
        }
    }
    return false;
};

11题目描述:

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

解析:

1.首先当数组的长度为1时,则直接返回数组中的第一个数即可
2.定义左右边界left和right,while循环满足left小于right时,定义中间节点mid
3.因为数组是旋转过来的,所以使用right和mid来判断,而不是left
4.当numbers[mid] < numbers[right]时,说明旋转点在右段,则right为mid
当numbers[mid] > numbers[right]时,说明旋转点在左端,则left等于mid+1
最后一种情况,当numbers[mid] = numbers[right]时,则right--
5.最后返回numbers[left]即可

Java:

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

JavaScript:

var minArray = function(numbers) {
    if(numbers.length === 1) {
        return numbers[0];
    }
    let left = 0;
    let right = numbers.length - 1;
    while(left < right) {
        let mid = Math.floor(left + (right - left) / 2);
        if(numbers[mid] < numbers[right]) {
            right = mid;
        } else if (numbers[mid] > numbers[right]) {
            left = mid + 1;
        } else {
            right--;
        }
    }
    return numbers[left];
};