劍指Offer面試題:2.二維數組中的查找


一、題目:二維數組中的查找

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

  例如下面的二維數組就是每行、每列都遞增排序。如果在這個數組中查找數字7,則返回true;如果查找數字5,由於數組不含有該數字,則返回false。

二、解題思路

  首先選取數組中右上角的數字。如果該數字等於要查找的數字,查找過程結束;如果該數字大於要查找的數字,剔除這個數字所在的列;如果該數字小於要查找的數字,剔除這個數字所在的行。也就是說如果要查找的數字不在數組的右上角,則每一次都在數組的查找范圍中剔除一行或者一列,這樣每一步都可以縮小查找的范圍,直到找到要查找的數字,或者查找范圍為空。

  例如,我們要在上述的二維數組中查找數字7的步驟如下圖所示:

  (矩陣中加陰影背景的區域是下一步查找的范圍)

三、解決問題

3.1 代碼實現

    // 二維數組matrix中,每一行都從左到右遞增排序,
    // 每一列都從上到下遞增排序
    public static bool Find(int[,] matrix, int rows, int columns, int number)
    {
        bool isFind = false;

        if (matrix != null && rows > 0 && columns > 0)
        {
            // 從第一行開始
            int row = 0;
            // 從最后一列開始
            int column = columns - 1;
            // 行:從上到下,列:從右到左
            while (row < rows && column >= 0)
            {
                if (matrix[row, column] == number)
                {
                    isFind = true;
                    break;
                }
                else if (matrix[row, column] > number)
                {
                    column--;
                }
                else
                {
                    row++;
                }
            }
        }

        return isFind;
    }

  在前面的分析中,我們每一次都是選取數組查找范圍內的右上角數字。同樣,我們也可以選取左下角的數字。但我們不能選擇左上角或者右下角。以左上角為例,最初數字1位於初始數組的左上角,由於1小於7,那么7應該位於1的右邊或者下邊。此時我們既不能從查找范圍內剔除1所在的行,也不能剔除1所在的列,這樣我們就無法縮小查找的范圍

3.2 單元測試

  (1)要查找的數字在數組中

    [TestMethod]
    public void FindTest1()
    {
        //  1   2   8   9
        //  2   4   9   12
        //  4   7   10  13
        //  6   8   11  15
        // 要查找的數在數組中
        int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        // 可以通過GetLength()方法獲取行數和列數
        //Assert.AreEqual(Program.Find(matrix, matrix.GetLength(0), matrix.GetLength(1), 7), true);
        Assert.AreEqual(Program.Find(matrix, 4, 4, 7), true);
    }

  (2)要查找的數不在數組中

    [TestMethod]
    public void FindTest2()
    {
        //  1   2   8   9
        //  2   4   9   12
        //  4   7   10  13
        //  6   8   11  15
        // 要查找的數不在數組中
        int[,] matrix = {{1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15}};
        Assert.AreEqual(Program.Find(matrix, 4, 4, 5), false);
    }

  (3)要查找的數是數組中最小的數字

    [TestMethod]
    public void FindTest3()
    {
        //  1   2   8   9
        //  2   4   9   12
        //  4   7   10  13
        //  6   8   11  15
        // 要查找的數是數組中最小的數字
        int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        Assert.AreEqual(Program.Find(matrix, 4, 4, 1), true);
    }

  (4)要查找的數是數組中最大的數字

    [TestMethod]
    public void FindTest4()
    {
        //  1   2   8   9
        //  2   4   9   12
        //  4   7   10  13
        //  6   8   11  15
        // 要查找的數是數組中最大的數字
        int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        Assert.AreEqual(Program.Find(matrix, 4, 4, 15), true);
    }

  (5)要查找的數比數組中最小的數字還小

    [TestMethod]
    public void FindTest5()
    {
        //  1   2   8   9
        //  2   4   9   12
        //  4   7   10  13
        //  6   8   11  15
        // 要查找的數比數組中最小的數字還小
        int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        Assert.AreEqual(Program.Find(matrix, 4, 4, 0), false);
    }

  (6)要查找的數比數組中最大的數字還大

    [TestMethod]
    public void FindTest6()
    {
        //  1   2   8   9
        //  2   4   9   12
        //  4   7   10  13
        //  6   8   11  15
        // 要查找的數比數組中最大的數字還大
        int[,] matrix = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
        Assert.AreEqual(Program.Find(matrix, 4, 4, 16), false);
    }

  (7)魯棒性測試,輸入空指針

    [TestMethod]
    public void FindTest7()
    {
        // 魯棒性測試,輸入空指針
        Assert.AreEqual(Program.Find(null, 0, 0, 16), false);
    }

  單元測試結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM