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


题意描述:

在一个 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。

解题思路:

Alice: 在二维数组中搜索一个数字是否存在 ?
Bob: 是的,但是数组内部是有序的,从上到下,从左到右递增。
Alice: 如果 第二行的第一个 要比 第一行的最后一个还要大,整个数组就可以看成一个一维的有序数组了,就可以直接用二分查找了。
Bob: hhh, 我们还是举个例子吧,没有例子不直观。
Alice: 那就假如是在

[[1,2,3], 
[2,5,6],
[3,8,9]]

里面寻找 6 这个元素 ?
Bob: 横着也有序,纵轴也有序。
Alice: 我明白了,这应该是个双指针的题目,如果我们能够找到两个方向,一个方向数组的值变小,一个方向数组的值变大,那我们就好像站在了一个一维数组的中间位置。
Bob: 一个方向变大,一个方向变小,那就应该是从下到上,从左到右,就是从左下角的位置开始搜索喽 ?
Alice: 是的,然后每到一个新的位置就再比较一下,最后直到到达最上边或者最右边。
Bob: 😎😎,其实从右上角开始搜素也可以的。


代码:

Python 方法一: 暴力查找:

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        for row in matrix:
            for num in row:
                if num == target:
                    return True
        return False

Python 方法二: 双指针

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:

        if len(matrix) == 0:
            return False

        x = len(matrix) - 1 
        y = 0

        while x >= 0 and y < len(matrix[0]):
            if matrix[x][y] == target:
                return True
            elif matrix[x][y] < target:
                y += 1
            else:
                x -= 1

        return False

Java 方法一: 暴力搜索 + 二分查找:

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        for(int[] array : matrix){
            if(binarySearch(array, target) == true){
                return true;
            }
        }
        return false;
    }
    public boolean binarySearch(int[] array, int target){
        int l = 0;
        int r = array.length - 1;
        while(l <= r){
            int middle = (l + r) / 2;
            if(array[middle] == target){
                return true;
            }else if(array[middle] < target){
                l = middle + 1;
            }else{
                r = middle - 1;
            }
        }
        return false;
    }
}

Java 方法二: 暴力搜索。

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        for(int[] row : matrix){
            for(int x : row){
                if(x == target){
                    return true;
                }
            }
        }
        return false;
    }
}

Java 方法三: 双指针:

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if(matrix.length == 0){
            return false;
        }else{
            int x = matrix.length - 1;
            int y = 0;
            while(x >= 0 && y < matrix[0].length){
                if(matrix[x][y] == target){
                    return true;
                }else if(matrix[x][y] < target){
                    y += 1;
                }else{
                    x -= 1;
                }
            }
            return false;
        }
    }
}

以下为牛客网平台代码

C++ 方法二: 暴力搜索。

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        for(int i=0; i<array.size(); ++i){
            for(int j=0; j<array[0].size(); ++j){
                if(array[i][j] == target){
                    return true;
                }
            }
        }
        return false;
    }
};

JS 方法一: 双指针。

function Find(target, array)
{
    // write code here
    var index1 = array.length - 1;
    var index2 = 0;
    while(index1 >= 0 && index2 < array[0].length){
        if(array[index1][index2] == target){
            return true;
        }else if(array[index1][index2] < target){
            index2 ++;
        }else{
            index1 --;
        }
    }
    return false;
    
}

JS 方法 一 :还是双指针,改变搜索的起始位置。

function Find(target, array)
{
    // write code here
    var index1 = 0;
    var index2 = array[0].length - 1;
    while(index1 < array.length && index2 >= 0){
        if(array[index1][index2] == target){
            return true;
        }else if(array[index1][index2] < target){
            index1 ++;
        }else{
            index2 --;
        }
    }
    return false;
    
}

JS 方法二: 暴力查找,O(n^2) 啊,居然也能过。

function Find(target, array)
{
    // write code here
    for(var i=0; i<array.length; ++i){
        for(var j=0; j<array[0].length; ++j){
            if(array[i][j] == target){
                return true;
            }
        }
    }
    return false;
}

易错点:

长度为 n 的数组下标的范围是 [ 0, n-1 ]


总结:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值