Leetcode 刷题笔记(二十三) ——动态规划篇之基础题目
文章目录
- 系列文章目录
- 前言
- 题录
- 509. 斐波那契数
- 70. 爬楼梯
- 746. 使用最小花费爬楼梯
- 62. 不同路径
- 63. 不同路径 II
- 53. 最大子数组和
- 343. 整数拆分
- 96.不同的二叉搜索树
系列文章目录
一、 数组类型解题方法一:二分法
二、数组类型解题方法二:双指针法
三、数组类型解题方法三:滑动窗口
四、数组类型解题方法四:模拟
五、链表篇之链表的基础操作和经典题目
六、哈希表篇之经典题目
七、字符串篇之经典题目
八、字符串篇之 KMP
九、解题方法:双指针
十、栈与队列篇之经典题目
十 一、栈与队列篇之 top-K 问题
十 二、二叉树篇之二叉树的前中后序遍历
十 三、二叉树篇之二叉树的层序遍历及相关题目
十 四、二叉树篇之二叉树的属性相关题目
十 五、 二叉树篇之二叉树的修改与构造
十 六、 二叉树篇之二叉搜索树的属性
十 七、二叉树篇之公共祖先问题
十 八、二叉树篇之二叉搜索树的修改与构造
十 九、回溯算法篇之组合问题
二 十、回溯算法篇之分割、子集、全排列问题
二十一、贪心算法篇之入门题目
二十二、贪心算法篇之进阶题目
更新中 … …
前言
刷题路线来自 :代码随想录
动态规划中每一个状态一定是由上一个状态推导出来的,例如青蛙跳台阶,第 N个台阶是从N -1 或者 N-2台阶上跳上来的。
解题步骤:
- 状态(dp数组以及下标的含义)
- 递推公式 和 循环结构
- 初始化
- 返回值
题录
509. 斐波那契数
Leetcode 链接
题解:
方式一:递归
class Solution {public int fib(int n) {if (n == 0 || n == 1) return n;return fib(n - 1) + fib(n - 2);}
}
方式二:动态规划
class Solution {public int fib(int n) {if (n == 0) return 0;if (n == 1) return 1;int[] dp = new int[n + 1];dp[0] = 0;dp[1] = 1;for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}
空间优化:
class Solution {public int fib(int n) {if (n == 0) return 0;if (n == 1) return 1;int a = 0;int b = 1;int res = 0;for (int i = 2; i <= n; i++) {res = a + b;a = b;b = res;}return res;}
}
70. 爬楼梯
Leetcode 链接
题解:
第 N 层楼梯是由第 N - 1 或 N - 2 层跳上来的
dp 数组
class Solution {public int climbStairs(int n) {if (n == 1) return 1;int[] dp = new int[n + 1];dp[0] = 1;dp[1] = 1;for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2];}return dp[n];}
}
746. 使用最小花费爬楼梯
Leetcode 链接
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
题解:
class Solution {public int minCostClimbingStairs(int[] cost) {int len = cost.length;int[] dp = new int[len];dp[0] = cost[0];dp[1] = cost[1];for (int i = 2; i < len; i++) {dp[i] = Math.min(dp[i - 1], dp[i - 2]) +cost[i];}return Math.min(dp[len - 1], dp[len - 2]);}
}
62. 不同路径
Leetcode 链接
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?
题解:
状态(i, j):从(0,0) 到(i, j)的路径个数
状态方程:F(i,j) = F(i-1,j) + F(i,j-1)
初始状态: F(0,0) = F(0,j) = F(i,0) = 1
class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m][n];for (int i = 0; i < m; i++) dp[i][0] = 1;for (int i = 0; i < n; i++) dp[0][i] = 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];}
}
优化:
状态(i,j):从(0,0) 到(i,j)的路径个数
状态方程:F(i,j) = F(i-1,j) + F(i,j-1)
初始状态:F(0,j) = F(i,0) = 0, F(0,1) = 1或者F(1,0) = 1
返回结果:F(row,col)
class Solution {public int uniquePaths(int m, int n) {int[][] dp = new int[m + 1][n + 1];dp[0][1] = 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][n];}
}
63. 不同路径 II
Leetcode 链接
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?网格中的障碍物和空位置分别用 1 和 0 来表示。
题解:
同上题,改变一下初始状态,第一排和第一列遇到石头将后边也初始化为 0,中间区域只让有石头的地方为 0
class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int row = obstacleGrid.length;int col = obstacleGrid[0].length;int[][] dp = new int[row][col];for (int i = 0; i < row && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;for (int j = 0; j < col && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1;for (int i = 1; i < row; i++) {for (int j = 1; j < col; j++) {if (obstacleGrid[i][j] == 0) {dp[i][j] = dp[i - 1][j] + dp[i][j -1];} else {dp[i][j] = 0;}}}return dp[row - 1][col - 1];}
}
优化:
class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int row = obstacleGrid.length;int col = obstacleGrid[0].length;int[][] dp = new int[row + 1][col + 1];dp[0][1] = 1;for (int i = 1; i <= row; i++) {for (int j = 1; j <= col; j++) {if (obstacleGrid[i - 1][j - 1] == 1) {dp[i][j] = 0;}else {dp[i][j] = dp[i][j - 1] + dp[i -1][j];}}}return dp[row][col];}
}
53. 最大子数组和
Leetcode 链接
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。
题解:
状态 dp[i]:算上 i 位置的最长连续子数组和
状态方程:dp[i] = Math.max(dp[i - 1] + nums[i], nums[i])
返回值:遍历过程中的 maxSum
class Solution {public int maxSubArray(int[] nums) {int[] dp = new int[nums.length];int maxSum = nums[0];dp[0] = nums[0];for (int i = 1; i < nums.length; i++) {dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);maxSum = Math.max(dp[i], maxSum);}return maxSum;}
}
343. 整数拆分
Leetcode 链接
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。返回 你可以获得的最大乘积 。
题解:
例:5 可以分解为 1 + 4 、2 + 3、3 + 2、4 + 1
dp[1] * 4、dp[2] * 3、dp[3] * 2 、dp[4] * 1、 但是这里并没有最大值
dp[2] = 1 * 1 = 1、dp[3] = 1 * 2 = 2、最大的 dp[3] * 2 = 4
最大的是6: 5 = 2 + 3、2 * 3 = 6
而对于较大的数是更是满足递推公式的,所以递推公式中有:Math.max(dp[j] * (i - j), j * (i - j))
状态 dp[i]:整数 i 的拆分最大乘积
状态方程: Math.max(dp[i], Math.max(dp[j] * (i - j), j * (i - j)));
也可以这么理解,j * (i - j) 是单纯的把整数拆分为两个数相乘,而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。
初始化:因为 k >= 2,dp[2] = 0
返回:dp[n]
class Solution {public int integerBreak(int n) {int[] dp = new int[n + 1];dp[2] = 1;for (int i = 3; i <= n; i++) {for (int j = 1; j <= i - 1; j++) {dp[i] = Math.max(dp[i], Math.max(dp[j] * (i - j), j * (i - j)));}}return dp[n];}
}
96.不同的二叉搜索树
Leetcode 链接
题解:
i 表示 为 n
j 表示以 j 为根节点
如:当 i = 3 时,j 分别为 1,2,3
class Solution {public int numTrees(int n) {int[] dp = new int[n + 1];dp[0] = 1;dp[1] = 1;for (int i = 2; i <= n; i++) {for (int j = 1; j <= i; j++) {dp[i] += dp[j- 1] * dp[i - j];}}return dp[n];}
}
Leetcode 刷题笔记(二十三) ——动态规划篇之基础题目相关推荐
- LeetCode刷题笔记- 15.三数之和
LeetCode刷题笔记- 15.三数之和 C语言 题目 注意点 C语言 /*** Return an array of arrays of size *returnSize.* The sizes ...
- 小何同学的leetcode刷题笔记 基础篇(01)整数反转
小何同学的leetcode刷题笔记 基础篇(01)整数反转[07] *** [01]数学取余法*** 对数字进行数位操作时,常见的方法便是用取余的方法提取出各位数字,再进行操作 操作(1):对10取余 ...
- 【leetcode刷题笔记】动态规划
#[leetcode刷题笔记]动态规划 石子游戏 public boolean stoneGame(int[] piles) {int N = piles.length;// dp[i][j] is ...
- LeetCode刷题笔记-动态规划-day4
文章目录 LeetCode刷题笔记-动态规划-day4 55. 跳跃游戏 1.题目 2.解题思路 3.代码 45. 跳跃游戏 II 1.题目 2.解题思路 3.代码 LeetCode刷题笔记-动态规划 ...
- LeetCode刷题笔记(算法思想 四)
LeetCode刷题笔记(算法思想 四) 七.动态规划 斐波那契数列 70. 爬楼梯 198. 打家劫舍 213. 打家劫舍 II 信件错排 母牛生产 矩阵路径 64. 最小路径和 62. 不同路径 ...
- LeetCode刷题笔记2——数组2
LeetCode刷题笔记2--数组2 重塑数组 题目 在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原 ...
- LeetCode刷题笔记汇总
LeetCode刷题笔记汇总 第一次刷LeetCode写的一些笔记. 1.两数之和 3.无重复字符的最长子串 15.三数之和 18.四数之和 19.删除链表的倒数第 N 个结点 20.有效的括号 21 ...
- leetcode刷题笔记——二分查找
leetcode刷题笔记--二分查找 目前完成的贪心相关的leetcode算法题序号: 中等:80,81 困难:4 来源:力扣(LeetCode) 链接:https://leetcode-cn.com ...
- 卷进大厂系列之LeetCode刷题笔记:二分查找(简单)
LeetCode刷题笔记:二分查找(简单) 学算法,刷力扣,加油卷,进大厂! 题目描述 涉及算法 题目解答 学算法,刷力扣,加油卷,进大厂! 题目描述 力扣题目链接 给定一个 n 个元素有序的(升序) ...
- LeetCode刷题笔记第6题:Z字形变换
LeetCode刷题笔记第6题:Z字形变换 想法: 要完成字符串根据给定的行数从上往下,从左到右完成Z字形排列.当只有一行时直接返回原字符串,当行数大于1时,先以行数构建一个行数数值个空字符串的列表, ...
最新文章
- 2W 字详解 Redis 6.0 集群环境搭建实践
- 2021年编程语言趋势预测:Python和JavaScript仍火热,Go不可小觑
- MYSQL——常用运算符和函数
- 你在京东购买的商品,是怎么出现在抖音里面的?
- Bootstrap+PHP fileinput 实现多图上传 这是ajax上传,只能单张单张图片地上传
- 转-Appium—驱动和常用功能的封装
- postman生成python代码_别再用手敲了,这个工具可以自动生成python爬虫代码
- 浅析Nginx 正向代理与反向代理
- Java日志框架之JUL(java util logging)详解
- 年轻人的第一台车“没了”,小米回应:新媒体同学抖错了机灵
- 小米10预计春节后见 售价超3500元没悬念
- aspnet_regsql.exe 工具参数解析
- 计算机技能大赛简讯内,【报道】2010学西城区职业高中计算机排版技能竞赛简讯...
- 在 360 度绩效评估中应该问的 20 个问题
- 怎样才能在微信朋友圈发长视频?
- 程序员面试之九阴真经
- pow函数以及math.h的一些坑
- android实现电话通信原理,电话通信原理.pdf
- convert函数用法小结
- OSChina 周二乱弹 —— 怎么制作妹子面