劍指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); }
單元測試結果:
作者:周旭龍
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。
相關推薦
劍指Offer面試題:2.二維陣列中的查詢
一、題目:二維陣列中的查詢 題目:在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。 例如下面的二維陣列就是每行、每列都遞增排序。如果在這個陣列中查詢數字7,則返回true;
劍指offer 面試題:重建二叉樹
題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。 思路:二叉樹先序是根左右,中序 是左根右。所以先找到
劍指Offer面試題:22.二叉搜尋樹的後序遍歷序列
一、題目:二叉搜尋樹的後序遍歷序列 題目:輸入一個整數陣列,判斷該陣列是不是某二叉搜尋樹的後序遍歷的結果。如果是則返回true,否則返回false。假設輸入的陣列的任意兩個數字都互不相同。 例如在下面的一顆二叉搜尋樹中,輸入陣列{5,7,6,9,11,10,8},則返回true,因為這個整數序列是
劍指Offer面試題:23.二叉樹中和為某一值的路徑
一、題目:二叉樹中和為某一值的路徑 題目:輸入一棵二叉樹和一個整數,打印出二叉樹中結點值的和為輸入整數的所有路徑。從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。例如輸入下圖中二叉樹和整數22,則打印出兩條路徑,第一條路徑包含結點10、12,第二條路徑包含結點10、5和7。 二叉
劍指Offer面試題:25.二叉搜尋樹與雙向連結串列
一、題目:二叉搜尋樹與雙向連結串列 題目:輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。比如輸入下圖中左邊的二叉搜尋樹,則輸出轉換之後的排序雙向連結串列。 二叉搜尋樹的節點定義如下,這裡使用C#語言描述:
劍指offer面試題:求二叉樹的映象(遞迴、迴圈解法及測試用例)
題目:給定二叉樹,將其變換為源二叉樹的映象。 二叉樹的定義如下: struct TreeNode { int val; TreeNode* left; TreeNode* right; }; 輸入描述: 二叉樹的映象定義: 源二叉樹
劍指Offer面試題:28.連續子陣列的最大和
一、題目:連續子陣列的最大和 題目:輸入一個整型陣列,數組裡有正數也有負數。陣列中一個或連續的多個整陣列成一個子陣列。求所有子陣列的和的最大值。要求時間複雜度為O(n)。例如輸入的陣列為{1,-2,3,10,-4,7,2,-5},和最大的子陣列為{3,10,-4,7,2},因此輸出為該子陣列的和18。
劍指offer(一)之二維陣列中的查詢
題目描述 在一個二維陣列中(每個一維陣列的長度相同),每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。 思路: 思路來源討論。。。 由於從上至下遞增,從左至右遞增 假定當前位置
牛客網劍指offer—題目一在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數
在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。 思路:因為是隻需判斷有無該整數,所以用bool函式,返回false或true 假設是這樣一個數組
劍指Offer面試題:21.從上到下列印二叉樹
一、題目:從上到下列印二叉樹 題目:從上往下打印出二叉樹的每個結點,同一層的結點按照從左到右的順序列印。例如輸入下圖中的二叉樹,則依次打印出8、6、10、5、7、9、11。 二叉樹節點的定義如下,採用C#語言描述: public class BinaryTreeNode
劍指offer——面試題15.2:判斷兩個整數m和n的二進制中相差多少位
end aps alt 試題 namespace different hide 判斷 img 1 #include"iostream" 2 using namespace std; 3 4 int CountDifferentBit(int m,int n)
牛客網線上程式設計專題《劍指offer-面試題39》二叉樹的深度
題目連結: 題目描述: 解題思路: 解法:遞迴的遍歷一棵數的左右子樹。 已經AC的程式碼: public class treeDepth39 { public class Tr
劍指offer面試題7:重建二叉樹(java實現)
題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹,假設輸入的前序遍歷和中序遍歷的結果都不含重複的數字。例如:輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6}則重建二叉樹:其中二叉樹的定義如下: * publi
劍指Offer面試題6 重建二叉樹
題目:輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入的前序遍歷序列{1,2,4,7,3,5,6,8}和後序遍歷序列{4,7,2,1,5,3,8,6},則重建出如圖所示的二叉樹 二叉樹結點定義如下:
劍指Offer面試題7 用二個棧實現佇列
題目:用2個棧實現一個佇列。佇列的宣告如下,請實現它的兩個函式appendTail和deleteHead,分別完成在佇列尾部插入結點和在佇列頭部刪除結點的功能。 佇列的宣告: template <typename T> class CQueue { publi
劍指offer 面試題:從尾到頭列印連結串列
題目:輸入一個連結串列,按連結串列值從尾到頭的順序返回一個ArrayList。 思路:有多種放法。(1)先反轉連結串列,再列印連結串列。(2)使用棧。 /** * struct ListNode { * int val; * struct ListNode *n
劍指Offer面試題:17.樹的子結構
一、題目:樹的子結構 題目:輸入兩棵二叉樹A和B,判斷B是不是A的子結構。例如下圖中的兩棵二叉樹,由於A中有一部分子樹的結構和B是一樣的,因此B是A的子結構。 該二叉樹的節點定義如下,這裡使用C#語言描述: public class BinaryTreeNode {
劍指Offer面試題:31.兩個連結串列的第一個公共節點
一、題目:兩個連結串列的第一個公共節點 題目:輸入兩個連結串列,找出它們的第一個公共結點。 連結串列結點定義如下,這裡使用C#語言描述: public class Node { public int key; public Node
劍指Offer面試題:14.連結串列的倒數第k個節點
PS:這是一道出境率極高的題目,記得去年參加校園招聘時我看到了3次,但是每次寫的都不完善。 一、題目:連結串列的倒數第k個節點 題目:輸入一個連結串列,輸出該連結串列中倒數第k個結點。為了符合大多數人的習慣,本題從1開始計數,即連結串列的尾結點是倒數第1個結點。例如一個連結串列有6個結點,從頭結點開始
劍指Offer面試題:4.從尾到頭列印連結串列
一、題目:從尾到頭列印連結串列 題目:輸入一個連結串列的頭結點,從尾到頭反過來打印出每個結點的值。 到解決這個問題肯定要遍歷連結串列。遍歷的順序是從頭到尾的順序,可輸出的順序卻是從尾到頭。也就是說第一個遍歷到的結點最後一個輸出,而最後一個遍歷到的結點第一個輸出。這就是典型的“後進先出”,我