二维数组的检索
题目要求是给出一个m*m的矩阵,里面的数满足从左往右,从上往下递增。要求检索目标是否在矩阵里。以下是我随便画的一个矩阵。
# 输入一个行列都递增的二维数组,判断某个元素是否在内
m = int(input())
grid = [[] for i in range(m)]
for i in range(m):
line = input().split(' ')
for j in range(len(line)):
grid[i].append(int(line[j]))
tar = int(input()) # 目标
暴力检索
首先,最容易想到的就是遍历,时间复杂度O(n²)
# offer03-solution 1
def Matrix_search(m, grid, tar):
for i in range(0,m,1):
for j in range(0, m, 1):
if tar == grid[i][j]:
print("True")
return
print("False")
return
Matrix_search(m, grid, tar)
简单省事,不费人脑费电脑,以数字7为例,检索的方式如下图。
左上角蛇形检索
合理利用从左往右,从上往下递增的条件是解题的关键,我们从左上角开始检索,如果目标比当前的位置大,就向右下移动,反之向左移动。这样需要加一个向右的指针来判断是否达到边界。时间复杂度O(nlogn)。
# offer03-solution 2
def Matrix_search(m, grid, tar):
i = j = p = 0 # i,j为矩阵指针,p为向右指针
if tar < grid[i][j]:
print("False")
return
while(True):
if tar == grid[i][j]:
print("True")
return
else:
if p == 0 and j < m-1 and tar >= grid[i][j+1]:
j += 1
elif i < m-1 and tar >= grid[i+1][j]:
i += 1
p = 0
elif j > 0:
j = j - 1
p = 1
else:
print("False")
return
Matrix_search(m, grid, tar)
以数字7为例,检索的方式如下图。
右上角蛇形检索
我们可以看到,这个回头和指针显得很蠢,所以能不能直接从右上(左下也是一样的)开始检索呢?时间复杂度也是O(nlogn)
# offer03-solution 3
def Matrix_search2(m, grid, tar):
i = 0
j = m-1
while(True):
if tar == grid[i][j]:
print("True")
return
elif tar > grid[i][j]:
i += 1
if i > m-1:
print("False")
return
else:
j -= 1
if j < 0:
print("False")
return
Matrix_search(m, grid, tar)
小结
在本题中,合理利用条件,然后改善流程,同时注意边界值,就可以达到最优的检索。