1. 程式人生 > >前端常見演算法面試題之 - 二維陣列中的查詢[JavaScript解法]

前端常見演算法面試題之 - 二維陣列中的查詢[JavaScript解法]

前端常見演算法面試題之 - 二維陣列中的查詢[JavaScript解法]

題目描述

在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。

輸入輸出分析

每當拿到一個演算法題的時候,不要腦子中稍微有點思路後,就開始寫程式碼。而是先把題目中規定的引數搞清楚,然後把引數的例子寫出來。

本題兩個引數舉例:

  1. 遞增二維陣列
1   2   8
9 2 4 9 12 4 7 10 13 6 8 11 15

注意 題目只說每一行是遞增的,沒有說增幅是多少,不要以為增幅是1。同時也沒有說行數和列數相等

  1. 要查詢的整數

比如:7、5、0、16

對應的輸出結果:true、false、false、false

實現思路

  1. 暴力遍歷法

面試官要的肯定不是這個結果,直接跳過

  1. 二分查詢法

仔細看這個二維陣列最右上角這個數。它所在的行,左面的數字比它小;所在的列,下面的數字比它大:

在這裡插入圖片描述

如果要查詢的數字比9大,那麼9所在的行就不用在比較了,接下來只需要比較9下面的所有行

在這裡插入圖片描述

如果要查詢的數字比9小,那麼9所在的列就不用在比較了,接下來只需要比較9左面的所有列

在這裡插入圖片描述

通過這一次的比較,我們就能得到一個新的範圍(矩形)。接著繼續利用新範圍右上角的數字,與要查詢的整數進行比較。比較過後,又能得到一個新的進一步縮小的範圍(矩形)。如此往復,直到找到目標整數,或者沒有找到。

每一次比較的過程,比較類似二分查詢

比如要查詢數字7,那麼查詢的路徑如下圖:

在這裡插入圖片描述

每一步都是通過比較所在行左面數字和所在列下面數字的大小,確定下一步指標的移動方向。

同理,我們還可以從矩形的左下角的數字開始比較

最後,別忘了要把特殊情況考慮進去,比如引數的特殊值

程式碼實現

function find(target, array) {
    let rows = 0; // 右上角數字所在的行
    let cols = array[0].length - 1; // 右上角數字所在的列
    let result = false;

    // 特殊情況判斷. 其他特殊情況比如target不在array裡,這裡不在列舉
    if(array.length === 0) return false;

    while(cols >= 0 && rows < array.length) {
        if(array[rows][cols] === target) {
            result = true;
            break;
        } else if(array[rows][cols] > target) {
            // 如果右上角數字比目標數字大,向左移動指標
            cols--;
        } else {
            // 如果右上角數字比目標數字小,向下移動指標
            rows++;
        }
    }

    return result;
}