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 ]


總結:


發佈了169 篇原創文章 · 獲贊 39 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章