class Solution { public int fib(int n) { if(n<=1){ return n; } int[] dp = new int[n+1]; //初始化 dp[0] = 0; dp[1] = 1; for(int i = 2;i class Solution { public int climbStairs(int n) { if(n<3){ return n; } int[] dp = new int[n+1]; //初始化 dp[1] = 1; dp[2] = 2; for(int i = 3;i class Solution { public int minCostClimbingStairs(int[] cost) { int[] dp = new int[cost.length+1]; //从0、1开始都不用钱 for(int i = 2;i class Solution { public int uniquePaths(int m, int n) { int[][] dp = new int[m][n]; //初始化 for(int i = 0;i class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] dp = new int[m][n]; //初始化,为0:只有一条路,路上还有障碍 //初始化,为1:只有一条路,路上无障碍 for(int i = 0;i ※
class Solution { public int integerBreak(int n) { int[] dp = new int[n+1]; //初始化 dp[2] = 1; for(int i = 3;i ※
class Solution { public int numTrees(int n) { int[] dp = new int[n+1]; //初始化 dp[0] = 1; dp[1] = 1; for(int i = 2;i 详见:代码随想录打卡-dp之背包问题-CSDN博客
198.打家劫舍
213.打家劫舍II
337.打家劫舍III
class Solution { public int rob(int[] nums) { if(nums==null || nums.length==0){ return 0; } if(nums.length==1){ return nums[0]; } int[] dp = new int[nums.length]; dp[0] = nums[0]; dp[1] = Math.max(nums[0],nums[1]); for(int i = 2;i 注意: Arrays.copyOfRange()方法会返回一个新的数组,其中包含原始数组 original 中从索引 from 到 to-1(不包含to)的元素
class Solution { public int rob(int[] nums) { if(nums==null || nums.length<1){ return 0; } if(nums.length==1){ return nums[0]; } return Math.max(robAction(Arrays.copyOfRange(nums,0,nums.length-1)),robAction(Arrays.copyOfRange(nums,1,nums.length))); } private int robAction(int[] nums){ int pre = 0,cur = 0,tmp; for(int i = 0;i 注意:本题dp数组就是一个长度为2的数组!
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public int rob(TreeNode root) { //后序遍历 //dp数组是一个长度为2的数组 //0:不偷该节点 1:偷该节点 int[] dp = new int[2]; dp = robAction(root); return Math.max(dp[0],dp[1]); } private int[] robAction(TreeNode root){ int[] res = new int[2]; if(root==null){ return res; } int[] left = robAction(root.left); int[] right = robAction(root.right); //不偷节点,左右子节点分别取最大的 res[0] = Math.max(left[0],left[1])+Math.max(right[0],right[1]); //偷节点,左右子节点都不能偷 res[1] = root.val+left[0]+right[0]; return res; } } 详见:代码随想录打卡-股票问题-CSDN博客
300.最长递增子序列
注意:dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度
初始化:全部为1,只要有一个数字,长度就为1开始(这里利用到了Arrays.fill()方法)
class Solution { public int lengthOfLIS(int[] nums) { //dp[i]表示以nums[i]结尾的最长递增子序列 int[] dp = new int[nums.length]; Arrays.fill(dp,1); int res = 1; for(int i = 0;i 674. 最长连续递增序列
注意:与上题的区别在于,这题要求连续
class Solution { public int findLengthOfLCIS(int[] nums) { //动态规划 int[] dp = new int[nums.length]; Arrays.fill(dp,1); int res = 1; for(int i = 1;inums[i-1]){ dp[i] = dp[i-1]+1; } res = Math.max(res,dp[i]); } return res; } } 718.最长重复子数组
注意:这里要求是连续的,所以不相等时的dp[i][j]不需要考虑了
class Solution { public int findLength(int[] nums1, int[] nums2) { int[][] dp = new int[nums1.length+1][nums2.length+1]; int res = 0; for(int i = 1;i 1143.最长公共子序列
注意:与上题区别是,本题不要求连续,故不相等的情况也要考虑
class Solution { public int longestCommonSubsequence(String text1, String text2) { //不要求连续 char[] ch1 = text1.toCharArray(); char[] ch2 = text2.toCharArray(); int[][] dp = new int[ch1.length+1][ch2.length+1]; int res = 0; for(int i = 1;i 1035.不相交的线
class Solution { public int maxUncrossedLines(int[] nums1, int[] nums2) { //问题转换:不连续、公共 int[][] dp = new int[nums1.length+1][nums2.length+1]; int res = 0; for(int i = 1;i 53.最大子数组和
注意:连续。并且要明确dp[i]的概念,是包含了i为下标的数的,所以要么是nums[i]加上前面的和,要么就是单独nums[i],也就是以nums[i]为一个新的开头
class Solution { public int maxSubArray(int[] nums) { //连续 int[] dp = new int[nums.length]; dp[0] = nums[0]; int res = nums[0]; for(int i = 1;i 详见:https://blog.csdn.net/supercool7/article/details/140353805?spm=1001.2014.3001.5502
647.回文子串
注意:本题要求连续,故只要已经不是回文,后面再加也一定不是回文了
注意遍历顺序需要根据推导顺序来
布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false
class Solution { public int countSubstrings(String s) { char[] ch = s.toCharArray(); boolean[][] dp = new boolean[ch.length][ch.length]; int res = 0;//记录回文字符数 //已默认初始化,dp为false for(int i = ch.length-1;i>=0;i--){ for(int j = i;j 516.最长回文子序列
注意:与上题的区别是,本题不要求连续!
class Solution { public int longestPalindromeSubseq(String s) { char[] ch = s.toCharArray(); int[][] dp = new int[ch.length][ch.length]; for(int i = ch.length-1;i>=0;i--){ //初始化 dp[i][i] = 1; for(int j = i+1;j