目录
64. 最小路径和
问题描述
给定一个包含非负整数的 m x n
网格 grid
,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例 1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:
输入:grid = [[1,2,3],[4,5,6]] 输出:12
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j] <= 100
思路与算法
动态规划。以dp(i,j)表示从格子起点触发到达(i,j)的最小总和路径的路径和。
由于只能向右或者向下移动,所以有以下递推关系:
For i=0, j>0, dp(i,j) = grid[0][j] + dp(0,j-1),因为只能从(0,j-1)到达(0,j)
For i>0, j=0, dp(i,j) = grid[i][0] + dp(i-1,0),因为只能从(i-1,0)到达(i,0)
For i>0, j>0, dp(i,j) = grid[i][j] + min(dp(i-1,j),dp(i,j-1)),因为可以从两个格点到达(i,j),选择其中总和较小的一个
代码实现
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
m = len(grid)
n = len(grid[0])
dp = [ n*[0] for i in range(m)]
dp[0][0] = grid[0][0]
for j in range(1,n):
dp[0][j] = grid[0][j] + dp[0][j-1]
for i in range(1,m):
dp[i][0] = grid[i][0] + dp[i-1][0]
for i in range(1,m):
for j in range(1,n):
dp[i][j] = grid[i][j] + min(dp[i-1][j],dp[i][j-1])
# print(dp)
return dp[m-1][n-1]
执行用时:48 ms, 在所有 Python3 提交中击败了70.30%的用户
内存消耗:16.7 MB, 在所有 Python3 提交中击败了20.34%的用户
221. 最大正方形
问题描述
在一个由 '0'
和 '1'
组成的二维矩阵内,找到只包含 '1'
的最大正方形,并返回其面积。
示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 输出:4
示例 2:
输入:matrix = [["0","1"],["1","0"]] 输出:1
示例 3:
输入:matrix = [["0"]] 输出:0
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j]
为'0'
或'1'
思路与算法1:暴力搜索
遍历每个格点。统计以每个格点为左上角的最大正方形面积。
查询最大正方形面积时,逐层向外扩展。碰到0格点或者越出边界即停止。
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
m,n = len(matrix),len(matrix[0])
def get(i,j):
if i>=m or j>=n:
return 0
else:
return int(matrix[i][j])
maxarea = 0
for i in range(m):
for j in range(n):
# print('.....',i,j)
if get(i,j) == 0:
continue
else:
# Find the max square with (i,j) as the top-left corner
area = 1
layer = 1
flag = True
while True:
for j1 in range(j,j+layer+1):
if get(i+layer,j1) ==0:
flag = False
break
if flag is False:
break
for i1 in range(i,i+layer+1):
if get(i1,j+layer)==0:
flag = False
break
if not flag:
break
# print(i,j,layer,flag)
area += 2*layer + 1
layer += 1
# print(i,j,layer,area)
maxarea = max(maxarea,area)
return maxarea
超时。
思路与算法2:动态规划
用 表示以 (i, j) 为右下角,且只包含 1 的正方形的边长最大值。如果我们能计算出所有
的值,那么其中的最大值即为矩阵中只包含 1 的正方形的边长最大值,其平方即为最大正方形的面积。
对于每个坐标 (i, j)进行考察:
- 如果matrxix[i][j]等于0,显然有
- 如果i或者j等于0,则
- 如果matrxix[i][j]等于1,动态转移方程为
class Solution:
def maximalSquare(self, matrix: List[List[str]]) -> int:
m,n = len(matrix),len(matrix[0])
ans = 0
for i in range(m):
for j in range(n):
if matrix[i][j] == "0":
matrix[i][j] = 0
elif (i==0 or j==0):
matrix[i][j] = 1
else:
matrix[i][j] = min(matrix[i-1][j],matrix[i][j-1],matrix[i-1][j-1]) + 1
ans = max(ans,matrix[i][j])
return ans*ans
执行用时:176 ms, 在所有 Python3 提交中击败了60.34%的用户
内存消耗:22.8 MB, 在所有 Python3 提交中击败了94.69%的用户