今天的题都比较难,所以说回溯和二维数组的结合是最难的
332. Reconstruct Itinerary
这道题有点类似于图做遍历,但是他没有visited的数组
Way1:
首先先把原有的array拆成dictionary,key是from,val是当前key所对应的所有的to的结合成的list。然后对key进行遍历。之后开始循环key并对val中的每个to做backtracking,直到当前的结果的array和ticket的数量差1既是最终结果
class Solution:
def findItinerary(self, tickets: List[List[str]]) -> List[str]:
dic=defaultdict(list)
for f,t in tickets:
dic[f].append(t)
res=["JFK"]
for airport in dic:
dic[airport].sort()
def dfs(start):
if len(res)==len(tickets)+1:
return True
for _ in dic[start]:
end=dic[start].pop(0)
res.append(end)
if dfs(end):
return True
res.pop()
dic[start].append(end)
dfs("JFK")
return res
51. N-Queens
这道题最开始看还以为要二维遍历,但是实际上并不用,因为每一行或者列上只能存在一个queen,所以只遍历行或者列即可
Way1:
遍历行,做是否可以放置的判断的时候遍历列,还有两个对角线,这样的话就保证所有情况全都考虑到了。如果符合放置,则对当前的总体结果进行下次的遍历(row+1)直到row==n为止
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
res=[]
path=[['.' for _ in range(n)] for _ in range(n)]
def isvalid(row,col):
for i in range(row):
if path[i][col]=='Q':
return False
i=row-1
j=col-1
while i>=0 and j>=0:
if path[i][j]=='Q':
return False
i-=1
j-=1
i=row-1
j=col+1
while i>=0 and j<n:
if path[i][j]=='Q':
return False
i-=1
j+=1
return True
def dfs(row):
if row==n:
tmp=[]
for tmp_r in path:
tmp.append("".join(tmp_r))
res.append(tmp)
for col in range(n):
if isvalid(row,col):
path[row][col]='Q'
dfs(row+1)
path[row][col]='.'
dfs(0)
return res
37. Sudoku Solver
这道题就没有办法简化了,只能是在遍历每一行每一列的情况下,做判断当前选的值是不是可以放置
Way1:
遍历每一个位置,每次用数字1-9去试,看是否当前行或者列或者小九宫格满足要求,如果满足,则进行backtracking
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
def isvalid(row,col,n):
for i in range(9):
if board[row][i]==str(n):
return False
for j in range(9):
if board[j][col]==str(n):
return False
tmp_row=(row//3)*3
tmp_col=(col//3)*3
for i in range(tmp_row,tmp_row+3):
for j in range(tmp_col,tmp_col+3):
if board[i][j]==str(n):
return False
return True
def dfs():
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j]!='.':
continue
for n in range(1,10):
if isvalid(i,j,n):
board[i][j]=str(n)
if dfs():
return True
board[i][j]='.'
return False
return True
return dfs()
总结: 总体来说backtracking很难,基本思路就是三步:终止条件,如果遍历(for),以及要不要做valid验证。
def backtracking():
if 终止条件: return
for in range():
if valid:
add
backtracking()
remove
相对来说与多维数组的结合是最难的