冲刺大厂每日算法&面试题,动态规划21天——第十六天

Posted 肥学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了冲刺大厂每日算法&面试题,动态规划21天——第十六天相关的知识,希望对你有一定的参考价值。

导读

肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。我们先来搞一下让大家最头疼的一类算法题,动态规划我们将进行为时21天的养成计划。还在等什么快来一起肥学进行动态规划21天挑战吧!!

21天动态规划入门

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例 1:


输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 13111 的总和最小。
示例 2:

输入:grid = [[1,2,3],[4,5,6]]
输出:12

由于路径的方向只能是向下或向右,因此网格的第一行的每个元素只能从左上角元素开始向右移动到达,网格的第一列的每个元素只能从左上角元素开始向下移动到达,此时的路径是唯一的,因此每个元素对应的最小路径和即为对应的路径上的数字总和。

对于不在第一行和第一列的元素,可以从其上方相邻元素向下移动一步到达,或者从其左方相邻元素向右移动一步到达,元素对应的最小路径和等于其上方相邻元素与其左方相邻元素两者对应的最小路径和中的最小值加上当前元素的值。由于每个元素对应的最小路径和与其相邻元素对应的最小路径和有关,因此可以使用动态规划求解。

创建二维数组 \\textitdpdp,与原始网格的大小相同,\\textitdp[i][j]dp[i][j] 表示从左上角出发到 (i,j)(i,j) 位置的最小路径和。显然,\\textitdp[0][0]=\\textitgrid[0][0]dp[0][0]=grid[0][0]。对于 \\textitdpdp 中的其余元素,通过以下状态转移方程计算元素值。

当 i>0i>0 且 j=0j=0 时,\\textitdp[i][0]=\\textitdp[i-1][0]+\\textitgrid[i][0]dp[i][0]=dp[i−1][0]+grid[i][0]。

当 i=0i=0 且 j>0j>0 时,\\textitdp[0][j]=\\textitdp[0][j-1]+\\textitgrid[0][j]dp[0][j]=dp[0][j−1]+grid[0][j]。

当 i>0i>0 且 j>0j>0 时,\\textitdp[i][j]=\\min(\\textitdp[i-1][j],\\textitdp[i][j-1])+\\textitgrid[i][j]dp[i][j]=min(dp[i−1][j],dp[i][j−1])+grid[i][j]。

最后得到 \\textitdp[m-1][n-1]dp[m−1][n−1] 的值即为从网格左上角到网格右下角的最小路径和。




class Solution 
    public int minPathSum(int[][] grid) 
        if (grid == null || grid.length == 0 || grid[0].length == 0) 
            return 0;
        
        int rows = grid.length, columns = grid[0].length;
        int[][] dp = new int[rows][columns];
        dp[0][0] = grid[0][0];
        for (int i = 1; i < rows; i++) 
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        
        for (int j = 1; j < columns; j++) 
            dp[0][j] = dp[0][j - 1] + grid[0][j];
        
        for (int i = 1; i < rows; i++) 
            for (int j = 1; j < columns; j++) 
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            
        
        return dp[rows - 1][columns - 1];
    



在一个由 ‘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
可以使用动态规划降低时间复杂度。我们用 \\textitdp(i, j)dp(i,j) 表示以 (i, j)(i,j) 为右下角,且只包含 11 的正方形的边长最大值。如果我们能计算出所有 \\textitdp(i, j)dp(i,j) 的值,那么其中的最大值即为矩阵中只包含 11 的正方形的边长最大值,其平方即为最大正方形的面积。

那么如何计算 \\textitdpdp 中的每个元素值呢?对于每个位置 (i, j)(i,j),检查在矩阵中该位置的值:

如果该位置的值是 00,则 \\textitdp(i, j) = 0dp(i,j)=0,因为当前位置不可能在由 11 组成的正方形中;

如果该位置的值是 11,则 \\textitdp(i, j)dp(i,j) 的值由其上方、左方和左上方的三个相邻位置的 \\textitdpdp 值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加 11,状态转移方程如下:

dp(i, j)=min(dp(i−1, j), dp(i−1, j−1), dp(i, j−1))+1
dp(i,j)=min(dp(i−1,j),dp(i−1,j−1),dp(i,j−1))+1



class Solution 
    public int maximalSquare(char[][] matrix) 
        int maxSide = 0;
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) 
            return maxSide;
        
        int rows = matrix.length, columns = matrix[0].length;
        int[][] dp = new int[rows][columns];
        for (int i = 0; i < rows; i++) 
            for (int j = 0; j < columns; j++) 
                if (matrix[i][j] == '1') 
                    if (i == 0 || j == 0) 
                        dp[i][j] = 1;
                     else 
                        dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
                    
                    maxSide = Math.max(maxSide, dp[i][j]);
                
            
        
        int maxSquare = maxSide * maxSide;
        return maxSquare;
    



面试题

这次讲一下关于二叉树的面试必备知识;
构建一个node对象:

public class node 
	public int val;
	public node left;//左孩子
	public node right;//右孩子
	public node() 
		
	
	public node(int val,node left,node right) 
		this.val=val;
		this.left=left;
		this.right=right;
	
	public node(int val, node left) 
		super();
		this.val = val;
		this.left = left;
	
	

 求⼆叉树的最⼩深度


public class minDepth 
	public static int depth(node root) 
		if(root==null)return 0;
		return getMin(root);
	
	public static int getMin(node root) 
		if(root==null)return Integer.MAX_VALUE;//int类型的最大值
		if(root.left==null&& root.right==null)
			return 1;
		
		return Math.min(getMin(root.left), getMin(root.right))+1;
	

特别介绍

📣小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶

📣python有趣练手项目里面包括了像《机器人尬聊》《恶搞程序》这样的有趣文章,可以让你快乐学python练手项目专栏

📣另外想学JavaWeb进厂的同学可以看看这个专栏:传送们

📣这是个面试和考研的算法练习我们一起加油上岸之路

点击直接资料领取

这里有python,Java学习资料还有有有趣好玩的编程项目,更有难寻的各种资源。反正看看也不亏。

以上是关于冲刺大厂每日算法&面试题,动态规划21天——第十六天的主要内容,如果未能解决你的问题,请参考以下文章

冲刺大厂每日算法&面试题,动态规划21天——第六天

冲刺大厂每日算法&面试题,动态规划21天——第九天

冲刺大厂每日算法&面试题,动态规划21天——第十天

冲刺大厂每日算法&面试题,动态规划21天——第五天

冲刺大厂每日算法&面试题,动态规划21天——第八天

冲刺大厂每日算法&面试题,动态规划21天——第三天