dp
sjphiChina
代码是最为耐心、最能忍耐和最令人愉快的伙伴,在任何艰难困苦的时刻,它都不会抛弃你。
展开
-
Palindrome Partitioning II
此题是在帮我们学习几种思维概念:1. 将单个字符串用二维数组表示matrix,matrix[i][j]代表,从字符i到字符j的一个子串,02. matrix[i][j]这个子串是否是回文,由字符i是否等于字符j和matrix[i+1][j-1]是否为回文决定3.对于matrix[i][j]这个子串,如果是回文,下刀在i-1处,于是得到,j处的下刀个数,寻回往复得到j处的最小下刀数。原创 2016-05-26 13:04:22 · 179 阅读 · 0 评论 -
Decode Ways
dp入门的中档题,不想多说啥了,过遍数吧。public class Solution { public int numDecodings(String s) { if (s == null || s.length() == 0) { return 0; } int [] res = new int[s.length原创 2016-06-12 02:27:11 · 239 阅读 · 0 评论 -
Paint Fence
这道题可以算是真正dp的经典入门题,自己一定得好好多多看看想想。给出一种思路,还有其他的,参看点击打开链接参看点击打开链接public class Solution { public int numWays(int n, int k) { int[] dp = {0, k, k*k, 0}; if (n <= 2) {原创 2016-06-06 19:29:38 · 503 阅读 · 0 评论 -
Maximal Square
参考点击打开链接,理解这个转移方程:dp[i][j] = matrix[i][j] == '1' ? Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])) + 1 : 0; public class Solution { public int maximalSquare(char原创 2016-06-14 12:26:44 · 224 阅读 · 0 评论 -
House Robber II
这道题我们犯了两个大的错误:1. 忘记数量为1和2的情况了;2. 最关键的,我们一定要明确动归取值的意义。如此题,当start为0,表示可以从0这个位置开始,但从取值来看,未必就必须从0开始,如果1位置数值大,当然就可以从1开始,至于位置2,则是比较位置0加位置2的值和位置1的值,所以///// dp[1] = Math.max(dp[0], nums[1]);原创 2016-06-15 11:16:24 · 226 阅读 · 0 评论 -
House Robber III
这道题一开始的确不好转化到tree的处理,这个学习了,最重要的是下面的错误,同上一题II,从根节点出发,这个无法变化,但若是从子节点出发,就完全可以是从子节点(这时相当于根)出发,或者,从子节点的子节点出发,所以必须要比较大小/** * Definition for a binary tree node. * public class TreeNode { * int val;原创 2016-06-15 11:42:36 · 250 阅读 · 0 评论 -
Paint House II
参考:点击打开链接第一层for是对所有房子的遍历,第二层则是对某一个房子所有颜色的遍历。所以如果,第二个房子看到此时颜色与第一个房子的颜色相同(最小的cost),那就选择另一颜色(次小的)。每个房子都要找到自身和上一个房子最小的cost和次小的cost。理解:if (prevIdx == k) { costs[i][k] = costs[i][k原创 2016-07-01 13:58:02 · 372 阅读 · 0 评论 -
Paint House
想想想public class Solution { public int minCost(int[][] costs) { if (costs == null || costs.length == 0) { return 0; } for (int i = 1; i < costs.length; i++) { cost原创 2016-06-16 02:46:08 · 272 阅读 · 0 评论 -
Maximum Subarray
经典dppublic class Solution { public int maxSubArray(int[] nums) { int[] sum = new int[nums.length]; int max = nums[0]; sum[0] = nums[0]; for (int i = 1; i < nums.l原创 2016-06-19 11:39:29 · 209 阅读 · 0 评论 -
Unique Paths
dp入门public class Solution { public int uniquePaths(int m, int n) { if(m<1||n<1){ return 0; } int [][] dp = new int[m][n]; for (int i = 0; i < m; i++) { dp[i][0] = 1;原创 2016-06-21 06:45:16 · 183 阅读 · 0 评论 -
Unique Paths II
承接上一题,注意的是,初始化的时候,若一个为1,其后的格子都为1.public class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { int m = obstacleGrid.length, n = obstacleGrid[0].length; if(m<1||n<原创 2016-06-21 07:49:40 · 201 阅读 · 0 评论 -
Word Break
此题用dp解,初始化一个s.length()+1的布尔数组,当中[0]用于初始状态。当中要明白的点是,肯定要从第一个字符开始匹配,那么遍历整个字典,每匹配了一个word,那对应的数组位置应该标为真值,没有匹配的位置仍保持假值。依次循环,如果这个字符串整个都能匹配,则在字符布尔数组的最后位置应该为真。public boolean wordBreak(String s, Set wordD原创 2016-05-23 16:47:01 · 225 阅读 · 0 评论 -
Climbing Stairs
dp入门题,用了两种方法,继早上的叶文洁代表人类的第一声啼哭,这是第二声!加油!dp,一定要解决!!!public class Solution { int [] array = null; public int climbStairs(int n) { if (n < 1) { return 0; } i原创 2016-06-09 08:38:25 · 277 阅读 · 0 评论 -
House Robber
这个就如同叶文洁代表人类向宇宙发出了第一声啼哭,我们终于第一次真正对dp发出了啼哭。相信这是一个里程碑,加油,好运!转移方程maxValArray[i] = Math.max(maxValArray[i - 2] + nums[i - 1], maxValArray[i - 1]);参考中有更优化的,不用dp数组,点击打开链接public class Solution {原创 2016-06-07 19:10:08 · 286 阅读 · 0 评论 -
Longest Common Subsequence
此题,两个字符串比较,一般记得先定义二维数组,各维代表一个字符串。matrix[i][j]代表:字符串a的从0到第i个字符和字符串b的从0到第j个字符的最长相同子序列长度。那么对于这个长度:如果i和j相等,那即为matrix[i-1][j-1](各自前一个字符串的最长相同子序列长度)加上 1(又一个相等的)如果不等,那即为,matrix[i-1][j-1],matrix[i][j-原创 2016-05-26 14:39:10 · 371 阅读 · 0 评论 -
Longest Common Substring
有了前面Longest Common Subsequence的练习,这个题可以照葫芦画瓢,但是要注意的是,是什么的值可以传递,最后要返回的值是存在哪里的。1. 这个是求子字符串,必须是连续的,即,如果i和j匹配,值只能从i-1,j-1处得到,再加一,如果不匹配,[i][j]即为0,不可传递。2. 最大值是单独保存的,因为最大值无法在数组中持续传递public class Solutio原创 2016-05-26 15:17:47 · 359 阅读 · 0 评论 -
Edit Distance
此题和之前的三道题很相近,都是要创建一个二维数组来解。但是注意数组要初始化,因为当前[i][j]是由[i-1][j-1], [i-1][j], [i][j-1]决定,而初始值若放到一个大循环来赋值会很复杂,同时数组长度定义为字符串长度+1。一定要明白的是我们所定义的数组,[i][j]到底代表的是什么,在我们这里,即字符串a的第i个字符和字符串b的第j个字符的最小编辑次数。那如果,i和j相等,其原创 2016-05-26 16:25:14 · 189 阅读 · 0 评论 -
Interleaving String
此题所犯的错误,参看leetcode。重点在于如何定义[i][j]到底代表啥,之后,必须严格按照状态转移方程来写code。值得反复理解,反复做public class Solution { public boolean isInterleave(String s1, String s2, String s3) { int l1 = s1.length();原创 2016-05-26 18:50:12 · 214 阅读 · 0 评论 -
Decode Ways
单序列问题,定义一个length+1的一维数组,状态:[i]代表到字符i-1时的方案个数最重要的,也是自己忽略的,个数可以为0,如1230public int numDecodings(String s) { // Write your code here if (s == null || s.length() == 0) {原创 2016-05-27 13:14:44 · 200 阅读 · 0 评论 -
backpackII
有了前一题的基础,此题就很直接了。前一题求重量,此题求的是价值,那么将重量换为价值即可。但是看看下面的一个bug,阴沟翻船啊!!!!!!咋搞的。。。。写的时候不看code吗/** * @param m: An integer m denotes the size of a backpack * @param A & V: Given n items with s原创 2016-05-27 18:04:49 · 336 阅读 · 0 评论 -
backpack
最后找到了一种容易理解的01背包问题解法。还是如何定义状态和状态转移方程我们定义了一个二维int数组,[i+1][j]代表前A[i]个物品在不超过j容量下,能取到的最大值。如果,第i个物品比当前容量大,则不放入A[i]物品,只用[i][j]即可;如果,第i个物品小于等于当前容量,则要比较:不放入A[i]物品时j容量能取得最大值,与,不放入A[i]物品时j-A[i]容量能取的最大原创 2016-05-27 17:38:18 · 321 阅读 · 0 评论 -
kSum
参考点击打开链接原文说的很好,尤其是使用三维动规数组dp[i][j][t],表示从0遍历到A[i]后找到的j个元素之和为t的情况的总数。最后返回从整个A数组找到的k个元素之和为target的情况总数即可。其余的就过遍数即可。/** * @param A: an integer array. * @param k: a positive integer (k原创 2016-05-28 18:45:31 · 368 阅读 · 0 评论 -
Distinct Subsequences
两个字符串,二维数组。关键在于状态转移方程的确定,不清楚的时候,请画图。同时请看下面的bug!!!!public class Solution { public int numDistinct(String s, String t) { if (s == null || t == null) { return 1;原创 2016-05-26 17:57:59 · 216 阅读 · 0 评论 -
Perfect Squares
原来是dp问题,最好解。转移方程:dp[i] = Math.min(dp[i], dp[i - j*j] + 1);求的是最小值public class Solution { public int numSquares(int n) { int max = (int)Math.sqrt(n); int[] dp = new int[n + 1]; A原创 2016-06-24 07:31:49 · 231 阅读 · 0 评论 -
Combination Sum IV
这个最后得用dp来做,自己一开始想到的递归在遇到如[1,2,3],target=32时会超时,因为会有181997601种可能,laptop运行了1小时都还没算完。。。 public static int combinationSum3(int[] nums, int target) { int[] array = new int[target + 1];原创 2016-09-02 08:18:17 · 306 阅读 · 0 评论