![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
Huiex胖子君
广告位招租
展开
-
剑指 Offer 46. 把数字翻译成字符串
动态规划 思路: 其实和青蛙跳台阶一个道理 当有 n 个数的排列方式为 1. 第n个数字无法和前面的数字无法组合时 排列方式为:前 n-1个数的排列方式 加上当前数字,数量为 fn-1(前n-1个数字饿排列方式) 2. 第n个数字可以和前面的数字组合时 排列方式为: 前 n-1个数的排列方式 加上当前数字,数量为 fn-1(前n-1个数字饿排列方式)和 前n-2个数的排列方式 (fn-2) 两种情况,只需要判断 第n个数字是否可以和前面的数字组合 如果组合的数字为 10 到 25 就说明可以组合 转移方程:原创 2021-12-04 12:37:11 · 62 阅读 · 0 评论 -
剑指 Offer 49. 丑数
动态规划 三指针 思想: 在已有的丑数序列上每一个数都必须乘2, 乘3, 乘5,然后选取其中最小的丑数,这样才不会漏掉某些丑数, 初始化: 第一个丑数为1,arr[0] = 1 转移方程: 丑数 == 某较小丑数 × 某因子 即 min = (a2,b3,c*5) 最优子结构: arr[a],arr[b],arr[c] 来自k神的图 /** 动态规划 三指针*/ public int nthUglyNumber(int n) { if (n == 0) return 0原创 2021-12-04 10:09:54 · 427 阅读 · 0 评论 -
剑指 Offer 14- I. 剪绳子
贪心 * 思想:当n大于4时,尽可能多的剪出长度为3的段,3就是最优的, * 当 n 被剪到小于4时,就不用再减,因为小于4时剪还不如不剪 * 如果给的n直接就小于4,没办法,特殊值,特殊处理,不剪也得剪 public int cuttingRope(int n) { if (n == 2) return 1; if (n == 3) return 2; if (n == 4) return 4; int res = 1;原创 2021-11-30 20:50:31 · 57 阅读 · 0 评论 -
剑指 Offer 62. 约瑟夫环问题(动态规划法)
https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/javajie-jue-yue-se-fu-huan-wen-ti-gao-su-ni-wei-sh/ fx = (fx + m) % i;转移方程就直接记住吧,可以照着这个图去穷举分析,理解一下这个方程 /** 动态规划 /数学解法 约瑟夫环*/ public int lastRemaining(int n, in原创 2021-11-29 21:22:10 · 210 阅读 · 0 评论 -
剑指 Offer 62. 约瑟夫环问题(模拟法)
不建议使用,时间复杂度太大,这个用了1361ms 用ArrayList会稍快一些 模拟时,重点在于 如何计算要删除数字的坐标,具体看注解 /** 模拟法*/ public int lastRemaining(int n, int m) { /** 创建一个集合用来模拟环*/ ArrayList<Integer> list = new ArrayList<>(); for (int i = 0; i < n; i++){原创 2021-11-29 21:15:48 · 183 阅读 · 0 评论 -
剑指 Offer 63. 股票的最大利润
当前天数的最大利润为 Math.max(前一天的最大利润,这一天的价钱减去前几天最小的价钱) 从第二天开始算起,也就是 i = 1; /** 当前天数的最大利润为 Math.max(前一天的最大利润,这一天的价钱减去前几天最小的价钱)*/ public int maxProfit(int[] prices) { if (prices.length == 0) return 0; /** 初始状态: 第一天的最大利润为 0 */ int fn =原创 2021-11-27 20:51:40 · 50 阅读 · 0 评论 -
剑指 Offer 10- II. 青蛙跳台阶问题(动态规划法)
使用动态规划 老三步 初始状态: f1 = 1,f2 = 2 转移方程: fn+1 = fn + fn-1 fn = fn-1 + fn-2 最优子结构: fn public int numWays(int n) { /** 初始状态: f1 = 1,f2 = 2 * 转移方程: fn+1 = fn + fn-1 * fn = fn-1 + fn-2 * 最优子结构: fn **原创 2021-11-27 17:21:40 · 128 阅读 · 0 评论 -
剑指 Offer 10- I. 斐波那契数列
典型动态规划 老三步 初始状态: f[1] = 1,f[0] = 0 转移方程: f[n+1] = f[n] + f[n-1] f[n] = f[n-1] + f[n-2]; 最优子结构: f[n] 注意一下题目要求的取模 public int fib(int n) { /** 初始状态: f[1] = 1,f[0] = 0 * 转移方程: f[n+1] = f[n] + f[n-1] * f[n] = f[n-原创 2021-11-27 17:19:18 · 119 阅读 · 0 评论 -
剑指 Offer 42. 连续子数组的最大和
看题目感觉是动态规划 然后列举分析一下,发现 过程中有些结果是重叠的 规律为 nums中索引为n的数,其子数组最大值为 Math.max(索引为 n-1的最大子数组加上自己本身(数组中该索引本身的数),自己本身) 得出: 初始状态:f0 = nums[0] 转移方程:fn+1 = fn + nums[n+1] 或 fn+1 fn = fn-1 + nums[n] 或 fn 最优子结构:fn /** 到索引为n的数,其子数组最大值为 索引为 Math.max(n-1的最大子数组加上自己,自己本身)*/原创 2021-11-27 17:16:46 · 189 阅读 · 0 评论 -
剑指 Offer 47. 礼物的最大价值
用动态规划 找规律,确定最优子结构 : 当前格子的累计最大价值为 上面和左边 的 最大累计价值 加上 当前格子的价值 即:dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j]) + grid[i][j] 确定边界: 第一个格子的最大累计价值就是当前格子价值 public int maxValue(int[][] grid) { /** 创建一个dp矩阵,用来存放到达单元格 (i,j)(i,j) 时能拿到礼物的最大累计价值。(可以理解为记事本)原创 2021-11-26 21:27:02 · 46 阅读 · 0 评论