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

Leetcode 刷题记录 19 —— 动态规划

本系列为笔者的 Leetcode 刷题记录,顺序为 Hot 100 题官方顺序,根据标签命名,记录笔者总结的做题思路,附部分代码解释和疑问解答,01~07为C++语言,08及以后为Java语言。

01 爬楼梯

在这里插入图片描述

在这里插入图片描述

class Solution {public int climbStairs(int n) {int a = 0, b = 0, c = 1; //边界条件for(int i=0; i<n; i++){a = b;b = c;c = a + b; //转移方程}return c;}
}/**边界条件:a = 0, b = 0, c = 1;转移方程:c = a + b;*/

02 杨辉三角

在这里插入图片描述

在这里插入图片描述

class Solution {public List<List<Integer>> generate(int numRows) {List<List<Integer>> c = new ArrayList<>(numRows);c.add(List.of(1)); //边界条件//一行一行计算for(int i=1; i<numRows; i++){List<Integer> row = new ArrayList<>(i + 1);row.add(1);for(int j=1; j<i; j++){row.add(c.get(i - 1).get(j - 1) + c.get(i - 1).get(j)); //转移方程}row.add(1);c.add(row);}return c;}
}/**边界条件:c.add(List.of(1));转移方程:row.add(c.get(i - 1).get(j - 1) + c.get(i - 1).get(j)); */

c.add(List.of(1));啥意思?

List.of(1):这是Java 9引入的一个静态方法,用来快速创建一个不可变(immutable)的列表,这里创建了一个只包含元素1的列表。

List<List<Integer>> c = new ArrayList<>(numRows);(numRows)啥意思?

这里的 numRows 作用是给 ArrayList 指定一个初始容量initial capacity),ArrayList 底层是用数组实现的,当你创建一个 ArrayList 时,如果指定了初始容量,ArrayList 会提前申请这么大容量的底层数组,避免插入元素时频繁扩容,提升效率。

03 打家劫舍

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

class Solution {public int rob(int[] nums) {//特殊情况判断if(nums.length == 0){return 0;}int n = nums.length;int[] dp = new int[n + 1];dp[0] = 0;dp[1] = nums[0]; //边界条件for(int i=2; i<=n; i++){dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]); //转移方程}return dp[n];}
}/**边界条件:dp[0] = 0; dp[1] = nums[0];转移方程:dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]);*/

04 完全平方数

在这里插入图片描述

在这里插入图片描述

class Solution {public int numSquares(int n) {int[] dp = new int[n + 1];for(int i=1; i<=n; i++){ //[1, n]dp[i] = i; //边界条件for(int j=1; j*j <= i; j++){ //[1, i]dp[i] = Math.min(dp[i], dp[i - j * j] + 1); //转移方程}}return dp[n];}
}/**边界条件:dp[i] = i;转移方程:dp[i] = Math.min(dp[i], dp[i - j * j] + 1);*/

05 零钱兑换

在这里插入图片描述

在这里插入图片描述

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++){ //遍历dp数组for(int j=0; j<coins.length; j++){ //遍历coins数组if(coins[j] <= i){dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1); //转移方程}}}return dp[amount] > amount ? -1 : dp[amount];}
}/**边界条件:dp[0] = 0;转移方程:dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);*/

Arrays.fill(dp, max);啥意思?

dp 是一个数组,max 是一个变量,表示你想赋给数组每个元素的值,Arrays.fill 是 Java 标准库中的一个静态方法,用来快速初始化或重置数组的值。

return dp[amount] > amount ? -1 : dp[amount];为啥就这么确定能找出正确组合,万一是1、2、5块的零钱,要求凑13,凑出来5、5、5块,返回-1了怎么办?

dp[0] = 0,其他dp[i]初始化为一个较大值(通常是amount+1或者类似的无穷大),对每一个硬币coin,遍历icoinamount,执行:

dp[i] = min(dp[i], dp[i - coin] + 1);

如果dp[i - coin]不可达(即是初始化的无穷大),则dp[i]不会被更新。

06 字符串拼接

在这里插入图片描述

在这里插入图片描述

class Solution {public boolean wordBreak(String s, List<String> wordDict) {Set<String> wordDictSet = new HashSet(wordDict);boolean[] dp = new boolean[s.length() + 1];dp[0] = true; //边界条件for(int i=1; i<=s.length(); i++){ //外层循环:i表示当前考虑字符串的前i个字符for(int j=0; j<i; j++){ //内层循环:j表示字符串拆分点if(dp[j] && wordDictSet.contains(s.substring(j, i))){ //转移方程dp[i] = true;break;}}}return dp[s.length()];}
}/**边界条件:dp[0] = true;转移方程:dp[j] && wordDictSet.contains(s.substring(j, i))*/

07 最长递增子序列

在这里插入图片描述

在这里插入图片描述

class Solution {public int lengthOfLIS(int[] nums) {if(nums.length == 0){return 0;}int ans = 1;int[] dp = new int[nums.length];dp[0] = 1;for(int i=1; i<nums.length; i++){dp[i] = 1;for(int j=0; j<i; j++){if(nums[i] > nums[j]){dp[i] = Math.max(dp[i], dp[j] + 1);}}ans = Math.max(ans, dp[i]);}return ans;}
}/**边界条件:dp[0] = 1;转移方程:dp[i] = Math.max(dp[i], dp[j] + 1);*/

for(int j=0; j<i; j++)为什么不是ji0j--,不然感觉好奇怪,感觉不是“连续”的递增子序列?

题目求的是“最长递增子序列(LIS)”,这里的子序列(subsequence)不是必须连续的。也就是说,元素的索引不必连续,只要保持递增顺序即可。

08 乘积最大子序列

在这里插入图片描述

在这里插入图片描述

class Solution {public int maxProduct(int[] nums) {int max = Integer.MIN_VALUE;int imax = 1, imin = 1;for(int i=0; i<nums.length; i++){if(nums[i] < 0){int temp = imax;imax = imin;imin = temp;}imax = Math.max(nums[i], imax * nums[i]);imin = Math.min(nums[i], imin * nums[i]);max = Math.max(max, imax);}return max;}
}

09 分割等和子集

在这里插入图片描述

class Solution {public boolean canPartition(int[] nums) {int n = nums.length;if(n < 2){return false;}int sum = 0, maxNum = 0;for(int num : nums){sum += num;maxNum = Math.max(maxNum, num);}if(sum % 2 != 0){return false;}int target = sum / 2;if(maxNum > target){return false;}//dp[i][j]//i 遍历元素//j 遍历目标值boolean[][] dp = new boolean[n][target + 1];for(int i=0; i<n; i++){dp[i][0] = true;}dp[0][nums[0]] = true;for(int i=1; i<n; i++){ //出错:i=1for(int j=0; j<=target; j++){if(j >= nums[i]){dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]];}else{dp[i][j] = dp[i-1][j];}}}return dp[n-1][target];}
}

10 最长有效括号

在这里插入图片描述

在这里插入图片描述

方法一:动态规划(简单)

class Solution {public int longestValidParentheses(String s) {int ans = 0;int[] dp = new int[s.length()];for(int i=1; i<s.length(); i++){if(s.charAt(i) == ')'){if(s.charAt(i-1) == '('){dp[i] = (i>=2 ? dp[i-2] : 0) + 2;}else if(i-dp[i-1] > 0 && s.charAt(i-dp[i-1]-1) == '('){dp[i] = dp[i-1] + (i-dp[i-1] >= 2 ? dp[i-dp[i-1]-2] : 0) + 2;}ans = Math.max(ans, dp[i]);}}return ans;}
}

方法二:栈

在这里插入图片描述

class Solution {public int longestValidParentheses(String s) {int ans = 0;Deque<Integer> stack = new LinkedList<>(); //记录括号下标stack.push(-1); //初始化for(int i=0; i<s.length(); i++){if(s.charAt(i) == '('){stack.push(i);}else{stack.pop();if(stack.isEmpty()){stack.push(i); //记录最后一个未被匹配的右括号下标}else{ans = Math.max(ans, i - stack.peek()); //可能是左括号、可能是右括号}}}return ans;}
}

相关文章:

  • 3分钟搭建LarkXR实时云渲染PaaS平台,实现各类3D/XR应用的一键推流
  • 氧化镱:稀土科技的“夜视高手”
  • dify私有化部署到ubuntu22.04(腾讯云为例)
  • 前缀二叉树(Trie树)详解
  • django基于Spark的国漫推荐系统
  • Early End是什么
  • Cesium快速入门到精通系列教程十:实现任意多个蜂巢似六边形组合
  • 数据结构----排序(3)
  • 接口联调阶段的移动端调试实践:从实际问题到流程协同(含WebDebugX)
  • MySQL 默认连接数
  • 在 HTTP 请求返回的状态码不为 200 时,重新发送请求
  • 数据库系统概论(十九)详细讲解关系查询处理与查询优化
  • 设计模式-依赖倒置原则(Dependency Inversion Principle, DIP)
  • Spring Boot(九十一):Spring Boot实现防盗链功能
  • WPS 和 office (word/excel/ppt) 找到模板所在位置以及更改模板的方式(公文写作格式要求、字体安装、模板下载)
  • Maven高级学习笔记
  • 常见哈希格式类型及其在CTF与渗透测试中的爆破与伪造策略(PBKDF2、bcrypt...)
  • Spring Boot分布式锁深度优化:彻底解决达梦数据库高并发死锁问题
  • 【C++11】智能指针——unique_ptr, shared_ptr和weak_ptr
  • DBeaver数据库管理工具的简介、下载安装与优化配置
  • 网站建设 计算机软件开发税点/真正免费的网站建站平台运营
  • 网站关键词提交/今日头条热搜榜
  • wordpress 导出数据库/广告优化师是做什么的
  • 大连seo建站公司/漳州网络推广
  • 济南网站制作设计公司/精准数据营销方案
  • 做破解网站合法/手机上制作网页