当前位置: 首页 > news >正文

代码随想录:动态规划6-10

62、不同路径

题目

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

示例 1:

输入:m = 3, n = 7
输出:28

代码

class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m][n]; //dp[i][j]表示走到该网格有几种路径//dp数组初始化,最上面和最左面要初始为1for(int i=0; i < m; i++){dp[i][0] = 1;}for(int j=0; j < n; j++){dp[0][j] = 1;}//遍历顺序:从左向右+从上到下for(int i=1; i < m ; i++){for(int j=1; j < n; j++){//该网格的路径=上面+左边之和dp[i][j] = dp[i-1][j] + dp[i][j-1]; }}return dp[m-1][n-1]; //返回最右下角的网格}
}

63、不同路径II

题目

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 1 和 0 来表示。

示例 1:

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右

代码

class Solution {//有障碍的初始化区别:网格有障碍,右边和下面的就不初始化1,默认0了//有障碍的递推区别:有障碍的不能用递推公式,默认=0public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m = obstacleGrid.length; //行数int n = obstacleGrid[0].length; //列数int[][] dp = new int[m][n];  //dp[i][j]表示走到这个网格的路径个数//dp数组初始化:无障碍左边和上面全为1,有障碍,不处理后面默认全为0for(int i=0; i < m && obstacleGrid[i][0] == 0; i++){dp[i][0] = 1;}for(int j=0; j < n && obstacleGrid[0][j] == 0; j++){dp[0][j] = 1;}//遍历顺序:从上往下+从左往右for(int i=1; i < m; i++){for(int j=1; j < n; j++){//无障碍=左边+上面之和if(obstacleGrid[i][j] == 0){dp[i][j] = dp[i-1][j] + dp[i][j-1];}//有障碍,该网格不能走,路径直接归零else{dp[i][j] = 0;}}}return dp[m-1][n-1]; //返回左下角}
}

343、整数拆分

题目

给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积 。

示例 1:

输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2:

输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

代码

class Solution {public int integerBreak(int n) {int[] dp = new int[n+1]; //dp[i]表示把i拆分的乘积最大值//dp数组初始化dp[1] = 0;  //0*1dp[2] = 1;  //1*1//遍历顺序,从3-n进行拆分,计算dp[i]for(int i=3; i <= n; i++){//对i进行拆分//用3举例:3=1+2/dp[2],3=2+1/dp[1]//用4举例:4=1+3/dp[3],4=2+2/dp[2],4=3+1/dp[1]for(int j=1; j < i; j++){int two = j * (i - j);  //把i拆成两数相乘int three = j * dp[i-j]; //把i拆成多数相乘//求max的时候dp[i]不能漏,因为two和three只是把i进行j的两种拆分,但不一定的dp[i]拆分的最大值dp[i] = Math.max(dp[i], Math.max(two, three));  //递推公式}}return dp[n];}
}

96、不同的二叉搜索树

题目

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。

示例 1:

输入:n = 3
输出:5

示例 2:

输入:n = 1
输出:1

代码

class Solution {public int numTrees(int n) {int[] dp = new int[n+1]; //dp[i]表示i个节点的二叉搜索树的个数//dp数组初始化dp[0] = 1;  //空树是一个二叉搜索树//遍历顺序:i从1-n分别计算二叉搜索树的个数dp[i]for(int i=1; i <= n; i++){//对i个节点进行拆分,以1为头结点-以i为头结点的情况分别求和,得到dp[i]for(int j=0; j < i; j++){//以i=3举例//dp[3] = 以1头结点+以2头结点+以3头结点//dp[3] = dp[0]*dp[2] + dp[1]*dp[1] + dp[2]*dp[0](左子树*右子树)int tmp = dp[j] * dp[i-1-j];  //递推公式dp[i] += tmp;}}return dp[n];  //返回n个节点的个数}
}


http://www.mrgr.cn/news/2914.html

相关文章:

  • 虚幻5|AI视力系统,听力系统,预测系统(1)视力系统
  • R语言:如何安装包“linkET”
  • 交换机怎么连线?一篇文章教你搞懂交换机的所有接口
  • 2024年企业图纸防泄密用什么加密?10款超好用的图纸加密软件推荐
  • NGINX 之 location 匹配优先级
  • 【Rust光年纪】探秘Rust语言数学优化库:从凸优化到线性规划
  • 如何提升 RocketMQ 顺序消费性能?
  • ISO 14001认证证书的有效期及年审要求
  • AtCoder Beginner Contest 367 A~F
  • Three.js可视化系统课程WebGL(24年3月最新版48章)
  • 口语笔记——连词
  • Java简易聊天工具(网络通信)
  • Linux下使用cat、grep、sed查看文件任意几行的数据
  • 大公报发表欧科云链署名文章:发行港元稳定币,建Web3.0新生态
  • IOS 12 自定义用户协议对话框
  • 多线程锁机制面试
  • Linux 离线安装docker和docker-compose
  • 领英(LinkedIn)公司主页创建方法分享
  • 【微信小程序】WXS脚本
  • 提取代理IP为何有最小提取间隔?如何获取自身业务有效时间代理?