今天時間不太多,記一道遇到的面試題:
題目
給定一個 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))
結論
第一次遇到深度優先搜索真題,有些懵,算是挺失敗的經歷,上面的代碼也只是簡單通過了能想到的測試例子,還是存在漏洞的,之後如果刷到更完善的題目再進行優化。
不過感覺也還不錯,之前的一系列練習也有效果,在有了深度優先搜索概念後也能獨立完成了,就是時間花費的有些誇張,繼續努力吧!