矩阵中的路径
题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
解题思路:
优化版回溯法
1.将matrix字符串模拟映射为一个字符矩阵(但并不实际创建一个矩阵)
2.取一个boolean[matrix.length]标记某个字符是否已经被访问过,用一个布尔矩阵进行是否存在该数值的标记。
3.如果没找到结果,需要将对应的boolean标记值置回false,返回上一层进行其他分路的查找。
代码:
# -*- coding:utf-8 -*-
class Solution:
def hasPath(self, matrix, rows, cols, path):
# write code here
if not matrix and rows<=0 and cols<=0 and path ==None:
return False
#模拟字符矩阵
markmatrix = [0]*(rows*cols)
pathlength = 0
# 从第一个开始递归,当然第一二个字符可能并不位于字符串之上,所以有这样一个双层循环找起点用的,一旦找到第一个符合的字符串,就开始进入递归,
# 返回的第一个return Ture就直接跳出循环了。
for row in range(rows):
for col in range(cols):
if self.hasPathCore(matrix, rows, cols, row, col, path, pathlength, markmatrix):
return True
return False
def hasPathCore(self, matrix, rows, cols, row, col, path, pathlength, markmatrix):
# 说明已经找到该路径,可以返回True
if len(path) == pathlength:
return True
hasPath = False
if row >= 0 and row < rows and col >= 0 and col < cols and matrix[row * cols + col] == path[pathlength] and not markmatrix[row * cols + col]:
pathlength += 1
markmatrix[row * cols + col] = True
# 进行该值上下左右的递归
hasPath = self.hasPathCore(matrix, rows, cols, row - 1, col, path, pathlength, markmatrix) or self.hasPathCore(matrix, rows, cols, row, col - 1, path, pathlength, markmatrix) or self.hasPathCore(matrix, rows, cols, row + 1, col, path, pathlength, markmatrix) or self.hasPathCore(matrix, rows, cols, row, col + 1, path, pathlength, markmatrix)
# 对标记矩阵进行布尔值标记
if not hasPath:
pathlength -= 1
markmatrix[row * cols + col] = False
return hasPath
# -*- coding:utf-8 -*-
class Solution:
def hasPath(self, matrix, rows, cols, path):
# write code here
for i in range(rows):
for j in range(cols):
if matrix[i*cols+j]==path[0]:
if self.find(list(matrix), rows, cols, path[1:],i,j):
return True
return False
def find(self, matrix, rows, cols, path, i,j):
if not path:
return True
matrix[i*cols+j]='0'
if j+1<cols and matrix[i*cols+j+1]==path[0]:
return self.find(matrix, rows, cols, path[1:], i,j+1)
elif j-1>=0 and matrix[i*cols+j-1]==path[0]:
return self.find(matrix, rows, cols, path[1:],i, j-1)
elif i+1<rows and matrix[(i+1)*cols+j] == path[0]:
return self.find(matrix, rows, cols, path[1:],i+1, j)
elif i-1>=0 and matrix[(i-1)*cols+j] == path[0]:
return self.find(matrix, rows,cols, path[1:],i-1,j)
else:
return False
机器人的运动范围
题目描述
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
解题思路:
与上题思路一样,判断条件改成了行坐标和列坐标的数位之和大于k
1.从(0,0)开始走,每成功走一步标记当前位置为true,然后从当前位置往四个方向探索,
返回1 + 4 个方向的探索值之和。
2.探索时,判断当前节点是否可达的标准为:
1)当前节点在矩阵内;
2)当前节点未被访问过;
3)当前节点满足limit限制。
代码:
# -*- coding:utf-8 -*-
class Solution:
def movingCount(self, threshold, rows, cols):
# write code here
markmatrix = [False]*(rows*cols)
count = self.GetNum(threshold, rows, cols, 0, 0, markmatrix)
return count
def GetNum(self, threshold, rows, cols,row,col, markmatrix):
count = 0
if self.GetSum(threshold, rows, cols, row, col,markmatrix):
markmatrix[row*cols+col] = True
count = 1+self.GetNum(threshold, rows, cols, row-1, col, markmatrix)+self.GetNum(threshold, rows, cols, row, col-1,markmatrix)+self.GetNum(threshold, rows, cols, row+1, col,markmatrix)+self.GetNum(threshold, rows, cols, row, col+1,markmatrix)
return count
def GetSum(self, threshold, rows, cols, row, col, markmatrix):
if row >=0 and row< rows and col>=0 and col<cols and self.getDigit(row)+self.getDigit(col)<=threshold and not markmatrix[row*cols+col]:
return True
return False
def getDigit(self, number):
sumNum = 0
while number>0:
sumNum += number%10
number = number /10
return sumNum