在一個 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。
解題思路:
因爲每行每列都按照從大到小順序排列,所以可以有如下思路:
對第i行,這一行最大的數必然是i[-1],最小的數必然是i[0],因此從第一行開始對每行進行遍歷:
- 如果target>該行最大數,則target必然在下一行或不存在,故直接遍歷下一行即可,即pass;
- 如果target<該行最小數,則target必然在之前的行,又因爲是從第一行開始遍歷的,所以必然不存在,返回False;
- 如果target不屬於上面兩種情況,那麼target可能在這一行,也可能在下一行,也可能不存在。下面對這一行按列遍歷:
- 如果target等於當前行當前列的數,則返回True;
- 如果target大於當前行當前列的數,那麼應該繼續遍歷下一個數,即pass;
- 如果target小於當前行當前列的數,那麼target要麼不存在要麼就在下一行,因此應該break;
當所有行遍歷完成後,如果還沒找到target,則說明不存在,返回False。
class Solution:
def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
# matrix[1][1]; matrix[-1][-1]
if len(matrix):
if len(matrix[0]):
m_min = matrix[0][0]
m_max = matrix[-1][-1]
if target < m_min or target > m_max:
return False
else:
rows = len(matrix)
cols = len(matrix[0])
for index in range(rows):
r_max = matrix[index][-1]
r_min = matrix[index][0]
if target > r_max: # 大於該行最大數,則必在後面的行
pass
elif target < r_min: # 小於最小數,則必不存在
return False
else: # 否則target要麼在這一行,要麼在下一行
for c_index in range(cols):
if matrix[index][c_index] == target: # 就是這個
return True
elif matrix[index][c_index] < target: # 繼續下一個
pass
else: # 大於情況一旦出現說明不在這一行
break
return False # 遍歷完成後還沒找到則不存在
else:
return False
else:
return False
問題總結:
1. 邏輯比較複雜,需要想清楚;
2. 對List[List[int]]的操作不太熟,還要堅持做題;
3. 對特殊情況的排除,即matrix=[]和matrix=[[]];
做題過程中出現過的錯誤及最後結果:
執行結果:通過
執行用時:56 ms, 在所有 Python3 提交中擊敗了32.04%的用戶
內存消耗:17.8 MB, 在所有 Python3 提交中擊敗了100.00%的用戶
看到的另一種巧妙的解法:(鏈接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/solution/gao-su-jie-fa-qing-xi-tu-jie-by-ml-zimingmeng/)
從左下角開始遍歷,當該值小於 target 值時,向右搜索;大於 target 值時,向上搜索。如果找到 target 則返回 True,否則返回 False。
妙啊!