今天时间不太多,记一道遇到的面试题:
题目
给定一个 m x n 的字符矩阵和字符串 s,在矩阵中每次只能横向、纵向移动一步,不能超出矩阵范围,问:是否可以由矩阵中拼接出 s?
题目分析
对深度优先搜索掌握并不到位,所以第一时间没有形成思路。直到后来确定是应用该算法后,才刚刚把答案完成。大致思路:用嵌套的列表来表示矩阵,首先遍历矩阵中的点,找到可以匹配字符串起点的点。
匹配到起点后,由该起点移动位置看能否完整匹配字符串 s,若可以、返回 True。将这个过程定义成独立的函数,在每次匹配到起点后调用,若全部起点都不能达到目标,最终返回 False。
代码实现
# 由矩阵中点向上下左右移动检索的函数
def search(tup,matrix,s):
# 如果字符串为空,单独处理
if not s:
return (-2,-2)
# 要匹配的字符 c 为字符串首字符
c = s[0]
# 获取当前被检测点座标
i,j = tup
# 获取座标范围
x = len(matrix)
y = len(matrix[0])
# 在边界范围内上下左右移动一格进行匹配检测,若成功,返回移动后坐标
if j>0:
if matrix[i][j-1]==c:
return (i,j-1)
if j<y-1:
if matrix[i][j+1]==c:
return (i,j+1)
if i>0:
if matrix[i-1][j]==c:
return (i-1,j)
if i<x-1:
if matrix[i+1][j]==c:
return (i+1,j)
# 若均不匹配成功,返回 (-1,-1)
return (-1,-1)
# 定义判断函数,输入矩阵 matrix 字符串 s
def judge(matrix,s):
# 判断匹配是否成功的变量
match = False
# 行座标范围
row_l = len(matrix[0])
# 列座标范围
col_l = len(matrix)
# 在行、列范围内遍历点 (p,q)
for p in range(col_l):
for q in range(row_l):
# 如果(p,q)可以匹配字符串起点
if matrix[p][q]==s[0]:
# 复制下座标
a,b = p,q
# 先将match赋值 True
match = True
# 如果被匹配字符串非空
while s:
# 字符串去掉首位重新赋值
s = s[1:]
# 调用检索函数,结果重新赋值给 a,b
a,b = search((a,b),matrix,s)
# 若函数返回 (-1,-1),匹配失败,跳出 while循环
if a==-1:
match = False
break
# 若while循环完整结束,则匹配成功,直接返回 True
if match:
return True
# 若中途未成功,返回 False
return False
matrix = [["a","b","c"],["k","f","g"],["e","a","k"],["p","m","n"]]
s = "ekabd"
s2 = "kfg"
print(judge(matrix,s))
print(judge(matrix,s2))
结论
第一次遇到深度优先搜索真题,有些懵,算是挺失败的经历,上面的代码也只是简单通过了能想到的测试例子,还是存在漏洞的,之后如果刷到更完善的题目再进行优化。
不过感觉也还不错,之前的一系列练习也有效果,在有了深度优先搜索概念后也能独立完成了,就是时间花费的有些夸张,继续努力吧!