62. 不同路径

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

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

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

例如,上图是一个7 x 3 的网格。有多少可能的路径?

示例 1:

输入: m = 3, n = 2

输出: 3

解释:

从左上角开始,总共有 3 条路径可以到达右下角。

  1. 向右 -> 向右 -> 向下
  2. 向右 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向右

    示例 2:

输入: m = 7, n = 3

输出: 28

提示:

1 <= m, n <= 100

题目数据保证答案小于等于 2 * 10 ^ 9

solution1 动态规划

class Solution {
public int uniquePaths(int m, int n) {
int[] col = new int[n]; //用数组记录之前列的路径
Arrays.fill(col,1);
for (int i=1; i<m; i++){
for (int j=1; j<n; j++){
col[j] += col[j-1];//第一行永为1,每一个点路径数等于左边+上边(col[j] = col[j]+col[j-1])
}
}
return col[n-1];
}
}
class Solution {
public int uniquePaths(int m, int n) {
int[][] chart = new int[m][n];
for (int i=0; i<m; i++) chart[i][0] = 1;
for (int i=0; i<n; i++) chart[0][i] = 1;
for (int i=1; i<m; i++){
for (int j=1; j<n; j++){
chart[i][j] = chart[i-1][j] + chart[i][j-1];
}
}
return chart[m-1][n-1];
}
}

63. 不同路径 II

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

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

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

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

说明:m 和 n 的值均不超过 100。

示例 1:

输入:

[

[0,0,0],

[0,1,0],

[0,0,0]

]

输出: 2

解释:

3x3 网格的正中间有一个障碍物。

从左上角到右下角一共有 2 条不同的路径:

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右

solution1 DP

class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int height = obstacleGrid.length;
int[] col = new int[height];
col[0] = 1;
for (int i=0; i<obstacleGrid[0].length; i++){
for (int j=0; j<obstacleGrid.length; j++){
if (obstacleGrid[j][i] == 1) col[j] = 0;
else if (j>0) col[j] += col[j-1];
}
}
return col[height-1];
}
}
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int width = obstacleGrid[0].length;
int[] dp = new int[width];
dp[0] = 1;
for (int[] row : obstacleGrid){
for (int i=0; i<width; i++){
if (row[i] == 1) dp[i] = 0;
else if (i>0) dp[i] += dp[i-1];
}
}
return dp[width-1];
}

322. 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1:

输入: coins = [1, 2, 5], amount = 11

输出: 3

解释: 11 = 5 + 5 + 1

示例 2:

输入: coins = [2], amount = 3

输出: -1

说明:

你可以认为每种硬币的数量是无限的。

solution1 暴力递归 (自顶向下)

class Solution {
public int coinChange(int[] coins, int amount) {
return helper(coins,amount);
}
public int helper(int[] coins, int n){
if(n == 0) return 0;
if(n < 0) return -1;
int res = n + 1;
for(int coin:coins){
int subres = helper(coins,n - coin); //状态转移方程
if(subres == -1) continue;
res = Math.min(res,subres+1);//最优子结构
}
return res >= n+1 ? -1:res;
}
}

solution2 带备忘录递归

class Solution {
public int coinChange(int[] coins, int amount) {
int[] count = new int[amount];
return helper(coins,amount,count);
}
public int helper(int[] coins, int n,int[] count){
if(n == 0) return 0;
if(n < 0) return -1;
if(count[n-1] != 0) return count[n-1];
int res = n + 1;
for(int coin:coins){
int subres = helper(coins,n - coin,count); //状态转移方程
if(subres == -1) continue;
res = Math.min(res,subres+1);//最优子结构
}
return count[n-1] = res >= n+1 ? -1:res;
}
}

solution3 动态规划 自底向上

class Solution {
public int coinChange(int[] coins, int amount) {
int max = amount + 1;
int[] dp = new int[amount+1];
Arrays.fill(dp,max);
dp[0] = 0;
for (int i = 1; i <= amount; i++){
for (int j = 0; j < coins.length; j++){
if(coins[j] <= i){
dp[i] = Math.min(dp[i],dp[i-coins[j]]+1); //状态转移方程
}
}
}
return dp[amount] > amount ? -1:dp[amount];
} }

思路

// 参考博客:https://leetcode-cn.com/problems/coin-change/solution/dong-tai-gui-hua-tao-lu-xiang-jie-by-wei-lai-bu-ke/
# 初始化 base case
dp[0][0][...] = base
# 进行状态转移
for 状态1 in 状态1的所有取值:
for 状态2 in 状态2的所有取值:
for ...
dp[状态1][状态2][...] = 求最值(选择1,选择2...)

887. 鸡蛋掉落

你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。

每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。

你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。

每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。

你的目标是确切地知道 F 的值是多少。

无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?

示例 1:

输入:K = 1, N = 2

输出:2

解释:

鸡蛋从 1 楼掉落。如果它碎了,我们肯定知道 F = 0 。

否则,鸡蛋从 2 楼掉落。如果它碎了,我们肯定知道 F = 1 。

如果它没碎,那么我们肯定知道 F = 2 。

因此,在最坏的情况下我们需要移动 2 次以确定 F 是多少。

示例 2:

输入:K = 2, N = 6

输出:3

示例 3:

输入:K = 3, N = 14

输出:4

提示:

1 <= K <= 100

1 <= N <= 10000

solution1 备忘录+递归

class Solution {
public int superEggDrop(int K, int N) {
int[][] menu = new int[K+1][N+1];
return helper(K,N,menu);
}
public int helper(int k, int n, int[][] menu){
//base case
if (k == 1) return n;
if (n == 0) return 0;
if (menu[k][n] != 0) return menu[k][n];
int res = Integer.MAX_VALUE;
for(int i = 1; i < n+1; i++){
//不碎,往上投还剩下n-i层 k不变
//碎了,往下投i-1,k-1
res = Math.min(res,Math.max(helper(k,n-i,menu),helper(k-1,i-1,menu))+1);
}
menu[k][n] = res;
return res;
}
}
//思路1:递归+备忘录
//1.dp数组,两个维度:还剩下几层 还剩多少鸡蛋(鸡蛋个数可以影响剩下投法,剩下层数影响鸡蛋怎么投)
//2.base case
//3.计算每一层投下后 碎和不碎两种情况下还要投的次数,取最小值

solution 2 二分查找优化

class Solution {
public int superEggDrop(int K, int N) {
return helper(K,N);
}
Map<Integer, Integer> memo = new HashMap();
public int helper(int k, int n){
//base case
if (k == 1) return n;
if (n == 0) return 0;
if (memo.containsKey(n*100+k)) return memo.get(100*n+k);
int res = Integer.MAX_VALUE;
//二分查找
int l = 1, r = n; while (l <= r){
int mid = (l+r) >> 1;
int noBroken = helper(k,n-mid);
int broken = helper(k-1,mid-1);
if (broken > noBroken){
r = r - 1;
res = Math.min(res,broken + 1);
}else{
l = l + 1;
res = Math.min(res,noBroken+1);
}
}
memo.put(n*100+k,res);
return memo.get(n*100+k);
}
}

LeetCode DP篇(62、63、322、887)的更多相关文章

  1. &lt;LeetCode OJ&gt; 62. / 63. Unique Paths(I / II)

    62. Unique Paths My Submissions Question Total Accepted: 75227 Total Submissions: 214539 Difficulty: ...

  2. Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II)

    Leetcode之动态规划(DP)专题-63. 不同路径 II(Unique Paths II) 初级题目:Leetcode之动态规划(DP)专题-62. 不同路径(Unique Paths) 一个机 ...

  3. LeetCode:零钱兑换【322】【DP】

    LeetCode:零钱兑换[322][DP] 题目描述 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成 ...

  4. 【leetcode】62.63 Unique Paths

    62. Unique Paths A robot is located at the top-left corner of a m x n grid (marked 'Start' in the di ...

  5. leetcode@ [62/63] Unique Paths II

    class Solution { public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleG ...

  6. [leetcode DP]63. Unique Paths II

    Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. How m ...

  7. [leetcode DP]62.Unique Paths

    判断一个物体从左上角到右下角有多少种走法 class Solution(object): def uniquePaths(self, m, n): flag = [[1 for j in range( ...

  8. [leetcode DP]64. Minimum Path Sum

    一个m*n的表格,每个格子有一个非负数,求从左上到右下最短的路径值 和62,63两个值是同一个思路,建立dp表,记录每个位置到右下角的最短路径的值 class Solution(object): de ...

  9. 【leetcode dp】629. K Inverse Pairs Array

    https://leetcode.com/problems/k-inverse-pairs-array/description/ [题意] 给定n和k,求正好有k个逆序对的长度为n的序列有多少个,0& ...

  10. 【leetcode dp】132. Palindrome Partitioning II

    https://leetcode.com/problems/palindrome-partitioning-ii/description/ [题意] 给定一个字符串,求最少切割多少下,使得切割后的每个 ...

随机推荐

  1. MySQL PXC集群新增一个高版本节点

    已有的一个 MySQL PXC 集群环境,因为种种原因仅剩一个节点 node1,需要新增一个集群节点 node2. node1 版本:donor version (8.0.21) node2 版本:l ...

  2. 【Dotnet 工具箱】基于 .NET 6 和 Angular 构建项目任务管理平台

    1.Reha 时间管理大师 Rhea 是一个基于 C# 和 .NET 6 开发的在线任务管理平台,类似于 禅道.Jira.Redmine, 滴答清单等. 支持多视图多维度统一管理任务.多级结构,工作区 ...

  3. virsh domxxx命令

    1. 摘要信息类 1.1 dominfo 获取配置等摘要信息 [root@hyperhost ~]# virsh dominfo --domain centos7.6 Id: 1 Name: cent ...

  4. P4899 [IOI2018] werewolf 狼人 题解

    P4899 [IOI2018] werewolf 狼人 题解 题目描述 省流: \(n\) 个点,\(m\) 条边,\(q\) 次询问,对于每一次询问,给定一个起点 \(S\) 和终点 \(T\) , ...

  5. CentOS7 Ceph分布式集群部署

    CentOS 7 下安装Ceph-nautilus 本问主要记录在CentOS 7下如何安装Ceph-nautilus,安装过程中遇到的一些问题及解决方法. 1.Ceph实验准备 以下是本次实验所用到 ...

  6. Python:发送邮件或发带附件的邮件

    在进行发邮件之前,首先了解两个模块:smtplib和email. smtplib模块主要是负责发送邮件的,是一个发邮件的动作,比如连接邮箱服务,登录邮箱,发送邮件等. email模块主要是负责构造邮件 ...

  7. 微信支付:wxpay.unifiedOrder(data)返回appid 与 openId 不配

    原因:小程序和APP.公众号等支付方式夸端口调用支付,后台配置多个appId时 A程序中的openid 在B程序中支付.即使用A程序的openid和B程序的appIdy去调用wxpay.unified ...

  8. Flask解决跨域问题

    什么是跨域问题 跨域问题指的是浏览器限制了从一个源(协议.域名.端口)访问另一个源的资源的行为,这个限制是浏览器的一个安全机制.如果一个网页从一个源加载了另一种类型的资源(例如 HTML.CSS.脚本 ...

  9. 马云说的AI电商时代是什么

    这两天非常火的就是马老师说的,我们已经进入了AI的电商时代.相信电商时代大家很容易理解,换一个简单的方式来说就是网上购物. AI相信大家已经很熟悉了,就是人工智能.早在十年前其实已经有AI人工智能的概 ...

  10. 1.5万字 + 25张图盘点RocketMQ 11种消息类型,你知道几种?

    大家好,我是三友~~ 故事的开头是这样的 最近有个兄弟私信了我一张截图 我一看截图内容,好家伙,原来是我一年多前立的flag 倒不是我忘了这件事,我后来也的确写了一篇的关于RocketMQ运行的原理的 ...