
DP
文章平均质量分 69
努力努力再努力r
这个作者很懒,什么都没留下…
展开
-
(M)Dynamic Programming: 413. Arithmetic Slices
先写出几个来看看,找找规律:A = {1,2,3,4,5,6,7}新建一个数组res,res[i]保存0~i这些数里的等差数列个数,那么:res[0] = 0;res[1] = 0;res[2] = {1,2,3}res[3] = {1,2,3} + {2,3,4} + {1,2,3,4}res[4] = {1,2,3} + {2,3,4} + {1,2,3,4} +原创 2017-10-01 10:37:23 · 145 阅读 · 0 评论 -
(M)Dynamic Programming:2 Keys Keyboard
这个题也是用的递归,回溯,不知道怎么用动态规划。类似的题用回溯的其实很多,就是这种给两种操作,求达到要求的时候操作次数最少能有几次。这道题就是,如果当前复制的东西加上当前字符串的个数到了n,就返回,如果不到n,就考虑两种情况,要么把现在所有的字符都复制再粘贴,要么还是粘贴上次复制的个数。这里我加了一个处理,如果当前复制的东西加上去之后超过了n,那么返回一个很大的数,因为不满足条件。class原创 2017-10-02 16:40:56 · 648 阅读 · 0 评论 -
(M)Dynamic Programming:Target Sum
这个题一开始我要用DFS,但是一直不知道 怎么得到次数,看了别人的答案发现可以在类里面定义一个全局的cnt:class Solution {public: int cnt = 0; int findTargetSumWays(vector& nums, int S) { findTargetSumWays(nums, 0, 0, S); r原创 2017-10-02 21:37:58 · 182 阅读 · 0 评论 -
(M)Dynamic Programming:516. Longest Palindromic Subsequence
这个题一开始没思路,看了别人的答案发现自己题意没理解好。理解好了其实很简单,典型的动态规划。套用别人写的思路:这个题的子问题是:任意一个该字符串的子串包含的回文串的长度,那么对于这个字符串的子串,我们可以用它在原字符串中的起始位置和结束位置来表示。因此,我们可以用一个二维数组来对子问题进行表示,dp[i][j]表示he longest palindromic subsequence's len原创 2017-10-04 12:18:26 · 147 阅读 · 0 评论 -
(M)Dynamic Programming,DFS:Shopping Offers
z这个题并不知道怎么用DP,感觉第一想到的是DFS,类似背包问题。看了别人的答案写的:class Solution {public: int shoppingOffers(vector& price, vector>& special, vector& needs) { int n = price.size(), res = 0; for(int i原创 2017-10-04 17:08:49 · 195 阅读 · 0 评论 -
(M)Dynamic Programming:377. Combination Sum IV
这道题一开始用的DFS,后来超时了。看了大神写的动态规划发现挺简单的,但是自己就是没找到递归关系,后来看到大神的博客,才想起来确实和climing stairs那道题很像。http://www.cnblogs.com/grandyang/p/5705750.html代码:class Solution {public: int combinationSum4(vector& n原创 2017-10-05 11:47:01 · 183 阅读 · 0 评论 -
(M)Dynamic Programming:62. Unique Paths
这道题DFS会超时,果断用动态规划。很多类似的题目,都是给出两种操作,问能达到某个目的的话有多少种方法。这种题的话,首先建立一个二维数组dp,这个二维数组最上面的一边初始化为1,最左面的一边初始化为1,这样中间的每个位置都是它上面的值加上左边的值:class Solution {public: int uniquePaths(int m, int n) { vecto原创 2017-10-05 15:42:38 · 182 阅读 · 0 评论 -
(M)Dynamic Programming:96. Unique Binary Search Trees
这个题想了好久没想出递归关系。看了别人的答案。对于一个给定的n,1~n的每一个数都可能是根。如果让i是根,那么1~n这些数被分成两部分,小于i的是左子树,大于i的是右子树。左子树个数*右子树个数就是以i为根的树的个数。class Solution {public: int numTrees(int n) { vector dp(n+1, 0); dp[原创 2017-10-05 18:51:39 · 165 阅读 · 0 评论 -
(M)Dynamic Programming:309. Best Time to Buy and Sell Stock with Cooldown
此题不会。看大神的分析:对于这一天是否持股只有两种状态:持股状态(buy),没有持股状态(sell,cooldown)。对于当天持股状态时,至当天的为止的最大利润有两种可能:1、今天没有买入,跟昨天持股状态一样;2、今天买入,昨天是冷却期,利润是前天卖出股票时候得到的利润减去今天股票的价钱。 二者取最大值。对于当天未持股状态,至当天为止的最大利润有两种可能:1、今天没有卖出,跟昨天未持原创 2017-10-05 21:10:43 · 277 阅读 · 0 评论 -
(M)Dynamic Programming:416. Partition Equal Subset Sum
这个题和之前的 (M)Dynamic Programming:Target Sum 很像。当时那个题就不明白。这次这个题包含了另一个问题,数组中是否有一个子数组,这个子数组的和等于目标值targetclass Solution {public: bool canPartition(vector& nums) { int all = accumulate(nums.be原创 2017-10-06 11:55:26 · 172 阅读 · 0 评论 -
(M)Dynamic Programming:646. Maximum Length of Pair Chain
我的思路:举个例子:[[1, 2], [2, 3], [3, 4], [4, 5]]建立一个数组res,res[i]表示0~i个pair最长的链。那么如果res[i]和res[j]满足要求,那么就有一个链是res[j] + 1,遍历所有的满足要求的res[j]+1,最长的res[j] + 1就是res[i]。但这样会有一个问题,比如[3, 4], [2, 3], [1,2]这样就找不到链,原创 2017-10-01 14:47:53 · 171 阅读 · 0 评论 -
(M)Dynamic Programming:343. Integer Break
我先列出几个来找规律:若n = 10,1,2,3,4,5,6,7,8,9,10。若在dp数组里存i的break乘积,则dp[] = 0,0,1,2,4,6,9,12,18,27,36。比如,8可以分解成1+7,2+6,3+5,那么就分别看1*dp[7],2*dp[6],3*dp[5]哪个最大即可。但是发现1~6这几个数不符合这个规律,所以单独写。我的代码:class Solutio原创 2017-10-01 15:53:47 · 151 阅读 · 0 评论 -
(M)Dynamic Programming:357. Count Numbers with Unique Digits
这个题一开始没有头绪,后来看了一下别人的思路,这个题可以这样想:设一个数组dp,dp[i]表示的n=i的时候的答案,举个例子,如果n=3,那么他等于n=2的时候不重复数字的个数加上三位数中不重复数字的个数。这样可以用动态规划:class Solution {public: int countNumbersWithUniqueDigits(int n) { vect原创 2017-10-01 17:53:11 · 158 阅读 · 0 评论 -
Dynamic Programming:121. Best Time to Buy and Sell Stock
这个题没想到怎么用动态规划,就暴力了,然后超时了,这是我超时了的代码:class Solution {public: int maxProfit(vector& prices) { int maxprofit = 0; vector profit(prices.size()); for(int i = 0; i < prices.siz原创 2017-09-24 12:31:39 · 162 阅读 · 0 评论 -
Dynamic Programming:70. Climbing Stairs
我发现我就完全没弄懂动态规划是什么。一开始我的代码是这样的:class Solution {public: int climbStairs(int n) { if(n == 1) return 1; if(n == 2) return 2; return climbStairs(n - 1原创 2017-09-24 13:04:17 · 306 阅读 · 0 评论 -
Dynamic Programming:53. Maximum Subarray
建立一个数组numsres,和array一样长,每一个位置i存放的是包括array[i]在内的最大的连续子数组的和。这样,如果numsres[i-1]小于0,说明numsres[i]就等于array[i]。否则numsres[i]就是numsres[i-1]+array[i]。贴上我的代码:class Solution {public: int maxSubArray(vector&原创 2017-09-24 15:34:49 · 142 阅读 · 0 评论 -
Dynamic Programming:198. House Robber
这个题我没有用动态规划。我是这样想的:假设每一家的钱nums是:5 1 7 3 2 4.我定义一个新的数组vector tmp(nums.size()),令dp[i]的含义是,抢劫nums[i]这一家的话能得到的最大收益。那么这个题的答案就是这个数组里最大的那个数。我的代码:class Solution {public: int rob(vector& nums) {原创 2017-09-28 19:39:48 · 218 阅读 · 0 评论 -
Dynamic Programming:303. Range Sum Query - Immutable
简单题,只要维护一个数组,i位置的含义是0~i闭区间的和。class NumArray {public: vector sums; NumArray(vector nums) { if(nums.size() != 0) { sums.push_back(nums[0]); for(int i =原创 2017-09-28 20:45:13 · 176 阅读 · 0 评论 -
(M)Dynamic Programming:338. Counting Bits
肯定不能把每一个数的每一位都找一遍。先写出几个来找规律,发现如果求num=i+1这个数字1的个数:if(i最后一位是0) i中1的个数+1else if(i倒数第2位是0) i中1的个数+0else if(i的倒数第3位是0) i中1的个数-1else if(i的倒数第4位是0) i中1的个数-2……else if(i的倒数第n位是0) i中1的个数-(n-2)cla原创 2017-09-28 22:09:28 · 147 阅读 · 0 评论 -
(M)Dynamic Programming:647. Palindromic Substrings
这个题我写的有点麻烦,又是在string下标上调了半天。感觉做这种编程题尽量还是避免这种复杂的下标变换,真的很容易出错。我的思路是,定义一个vector dp(n, 0),从后往前遍历字符串,比如,遍历字符串第i个位置s[i],只需要求以s[i]开头的回文子串个数ni。那么s[i, s.size()-1]这个子串的所有回文子串就是ni + dp[i + 1]+...+dp[n]。动态规划就出来了。原创 2017-09-28 23:09:01 · 162 阅读 · 0 评论 -
(M)Dynamic Programming:392. Is Subsequence
这个题除了遍历之外没想到别的方法,用递归的写法发现报出内存不够的错误,最后还是用了for循环:class Solution {public: bool isSubsequence(string s, string t) { int m = s.size(); int n = t.size(); int iter1 = 0, iter2原创 2017-10-02 15:51:21 · 151 阅读 · 0 评论 -
(M)Dynamic Programming:486. Predict the Winner
碰到这种博弈的题就没思路。看了别人的代码之后才写出来的,这其实是用了回溯,我设一个用来递归的函数,start和end表示当前没有被选择过的区间,score1和score2表示这一轮开始时双方的分数,注意,这个题我一开始没写对就是因为少了player这个参数,player表示这一轮是谁取数,也可以看做在当前游戏状态下谁是先取的那个人,函数返回的是player这个人是否能赢。如果数组只剩下一个数了,那原创 2017-10-02 10:57:20 · 130 阅读 · 0 评论 -
(M)Dynamic Programming: 474. Ones and Zeroes
没找到递归表达式:看大神的分析:所以我们需要建立一个二位的DP数组,其中dp[i][j]表示有i个0和j个1时能组成的最多字符串的个数,而对于当前遍历到的字符串,我们统计出其中0和1的个数为zeros和ones,然后dp[i - zeros][j - ones]表示当前的i和j减去zeros和ones之前能拼成字符串的个数,那么加上当前的zeros和ones就是当前dp[i][j]可以达到的个原创 2017-10-06 16:22:11 · 254 阅读 · 0 评论 -
(M)Dynamic Programming:64. Minimum Path Sum
这个题还挺简单的,递归关系很好找,类似 (M)Dynamic Programming:62. Unique Paths。class Solution {public: int minPathSum(vector>& grid) { int m = grid.size(); int n = grid[0].size(); vector>原创 2017-10-06 16:36:07 · 189 阅读 · 0 评论 -
(M)Dynamic Programming:576. Out of Boundary Paths
看大神分析:使用一个三维的DP数组,其中dp[k][i][j]表示总共走k步,从(i,j)位置走出边界的总路径数。那么我们来找递推式,对于dp[k][i][j],走k步出边界的总路径数等于其周围四个位置的走k-1步出边界的总路径数之和,如果周围某个位置已经出边界了,那么就直接加上1,否则就在dp数组中找出该值,这样整个更新下来,我们就能得出每一个位置走任意步数的出界路径数了,最后只要返回dp[原创 2017-10-08 20:51:29 · 237 阅读 · 0 评论 -
(M)Dynamic Programming:139. Word Break
建一个数组dp,dp[i]表示0~i是否可以被分成字典里的单词。遍历0到i的每个位置j,若0~j可以被分割成单词,那么只需要知道j~i是否在字典里就可以了。class Solution {public: bool wordBreak(string s, vector& wordDict) { int n = wordDict.size(); int l原创 2017-10-08 22:42:42 · 191 阅读 · 0 评论 -
(M)Dynamic Programming:221. Maximal Square
大神分析:建立一个二维dp数组,其中dp[i][j]表示到达(i, j)位置所能组成的最大正方形的边长。对于任意一点dp[i][j],由于该点是正方形的右下角,所以该点的右边,下边,右下边都不用考虑,关心的就是左边,上边,和左上边。这三个位置的dp值suppose都应该算好的,还有就是要知道一点,只有当前(i, j)位置为1,dp[i][j]才有可能大于0,否则dp[i][j]一定为0。当(i原创 2017-10-09 09:43:47 · 164 阅读 · 0 评论 -
(M)Dynamic Programming:322. Coin Change
这道题不难,设一个dp数组,长度是ammount+1,初始化为-1。其中dp[i]表示钱数为i时的最小硬币数的找零,coins[j]为第j个硬币,而i - coins[j]为钱数i减去其中一个硬币的值,剩余的钱数在dp数组中找到值,然后加1和当前dp数组中的值做比较,取较小的那个更新dp数组。class Solution {public: int coinChange(vector&原创 2017-10-09 13:23:33 · 139 阅读 · 0 评论 -
(M)Dynamic Programming:152. Maximum Product Subarray
乘法和加法不同,累加结果只要是正就一定递增,乘法可能上一个结果为负值,后面再出现(不需要相邻)另外一个负数相乘就会得到更大的乘积(负负为正)。所以我们这里需要维护三个变量,局部最大,局部最小,全局最大。这题里需要维护的当前最大值和当前最小值,都是在dp_min[i-1] * A[i],dp_max[i] * A[i],和A[i]这三者里面取一即可。class Solution {public原创 2017-10-09 14:47:04 · 171 阅读 · 0 评论 -
(M)Dynamic Programming:304. Range Sum Query 2D - Immutable
这道题是受了(M)Dynamic Programming:221. Maximal Square的启发,写法一样的。建立一个二维数组dp,dp[i][j]表示(0,0)到(i,j)的矩阵之和。如果要求的正方形是(x1,y1),(x2,y2),那么要考虑dp(row1-1,col2),dp(row2, col1-1),dp(row1-1,col1-1)。class NumMatrix {p原创 2017-10-09 19:20:54 · 213 阅读 · 0 评论 -
(M)Dynamic Programming:464. Can I Win
抄袭大神:使用哈希表来记录已经计算过的结果。我们首先来看如果给定的数字范围大于等于目标值的话,直接返回true。如果给定的数字总和小于目标值的话,说明谁也没法赢,返回false。然后我们进入递归函数,首先我们查找当前情况是否在哈希表中存在,有的话直接返回即可。我们使用一个整型数按位来记录数组中的某个数字是否使用过,我们遍历所有数字,将该数字对应的mask算出来,如果其和used相与为0的话,说原创 2017-10-09 21:04:43 · 218 阅读 · 0 评论 -
(M)Dynamic Programming:523. Continuous Subarray Sum
这道题一开始理解错了题意,后来发现大神的解法也很暴力:遇到这种求子数组或者子矩阵之和的题,应该不难想到要建立累加和数组或者累加和矩阵来做。没错,这道题也得这么做,我们要遍历所有的子数组,然后利用累加和来快速求和。在得到每个子数组之和时,我们先和k比较,如果相同直接返回true,否则再判断,若k不为0,且sum能整除k,同样返回true,最后遍历结束返回false。(不太懂这里为什么要先和k原创 2017-10-09 22:16:43 · 339 阅读 · 0 评论 -
(M)Dynamic Programming:91. Decode Ways
看大神的分析:这道题要求解码方法,跟之前那道 Climbing Stairs 爬梯子问题 非常的相似,但是还有一些其他的限制条件,比如说一位数时不能为0,两位数不能大于26,其十位上的数也不能为0,出去这些限制条件,根爬梯子基本没啥区别,也勉强算特殊的斐波那契数列,当然需要用动态规划Dynamci Programming来解。建立一位dp数组,长度比输入数组长多多2,全部初始化为1,因为斐原创 2017-10-09 23:08:12 · 165 阅读 · 0 评论 -
(M)Dynamic Programming:673. Number of Longest Increasing Subsequence
这个题并不难,但是我一开始递归关系找错了。这个题考虑建立两个dp数组,一个存最长递增数组的长度,另一个存这个长度有多少条。下面是参考讨论区解法之后我的AC的代码:class Solution {public: int findNumberOfLIS(vector& nums) { int n = nums.size(); if(n == 0)原创 2017-10-08 20:11:21 · 167 阅读 · 0 评论 -
(M)Dynamic Programming:95. Unique Binary Search Trees II
递归方法:找到一个数作为根结点,剩余的数分别划入左子树或者右子树。class Solution { public: vector generateTrees(int n) { if(n == 0) { vector v; return v; } return c原创 2017-10-07 22:20:08 · 187 阅读 · 0 评论 -
(M)Dynamic Programming:63. Unique Paths II
这个题和Unique Paths差不多,就是在算dp[i][j]的时候,要考虑它的上边和左边是否有障碍物,只加没有障碍物的那个。最后要注意,如果右下角也就是目的地的位置是障碍物,那么要返回0.class Solution {public: int uniquePathsWithObstacles(vector>& obstacleGrid) { int m = obs原创 2017-10-07 21:12:03 · 162 阅读 · 0 评论 -
(M)Dynamic Programming:300. Longest Increasing Subsequence
建一个一维dp,长度为n,dp[i]表示包含nums[i]这个数字的最长的递增子序列长度。这个长度怎么找,就是要遍历nums[i]之前的这些数字,如果nums[j]class Solution {public: int lengthOfLIS(vector& nums) { int n = nums.size(); if(n == 0)原创 2017-10-06 17:07:45 · 177 阅读 · 0 评论 -
(M)Dynamic Programming:279. Perfect Squares
这个题不难想方法,列出n=12的情况就可以看出递归关系。但是用到了判断一个数是不是完全平方数的方法,还有INT_MAX那里,一开始初始化为1,发现不对。判断是不是平方数,一开始我写的是:if(sqrt(i) * sqrt(i) == i),后来发现不对,在i=11的时候出错。class Solution {public: int numSquares(int n) {原创 2017-10-06 17:43:54 · 177 阅读 · 0 评论 -
(M)Dynamic Programming:376. Wiggle Subsequence
想到Best Time to Buy and Sell Stock with Cooldown这个题的做法,建立两个数组,一个叫increase[],另一个叫decrease[],increase[i]表示nums[i]比前一个数字大的情况下的最长序列,decrease[i]表示nums[i]比前一个数字小的最长序列,两个数组取最长的就可以。class Solution {public:原创 2017-10-06 20:06:36 · 182 阅读 · 0 评论 -
(M)Dynamic Programming:688. Knight Probability in Chessboard
class Solution {public: double knightProbability(int N, int K, int r, int c) { int moves[8][2] = {{1, 2}, {1, -2}, {2, 1}, {2, -1}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}}; int len原创 2017-10-06 22:51:40 · 268 阅读 · 0 评论