动态规划

 1 class Solution {
 2 public:
 3     int minDistance(string word1, string word2) {
 4         if(word1.size()==0||word2.size()==0)
 5             return max(word1.size(),word2.size());
 6         vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
 7         for(int i=1;i<=word1.size();i++){
 8             dp[i][0] = i;
 9         }
10         for(int i=1;i<=word2.size();i++){
11             dp[0][i] = i;
12         }
13         for(int i=1;i<=word1.size();i++){
14             for(int j=1;j<=word2.size();j++){
15                 if(word1[i-1]==word2[j-1])
16                     dp[i][j] = dp[i-1][j-1];
17                 else
18                     dp[i][j] = min(min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1])+1;
19                 cout<<dp[i][j]<<" ";
20             }
21             cout<<endl;
22         }
23         return dp[word1.size()][word2.size()];
24     }
25 };
View Code

 

###时间复杂度上,1e8或者1e9都是一个for,不超过1e4两个for,1s计算机应该算1e9这么多次

###逻辑上无非就是相等会怎么样不相等怎么样

步骤:

确定dp数组及其下标含义(hcl:要 求啥dp数组的dp[i]就是啥)

确定递推公式

初始化dp数组

确定遍历顺序

举例推导dp数组

509. 斐波那契数 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int fib(int n) {
 4         if(n<2)
 5             return n;
 6         vector<int> dp(n+1);
 7         dp[0] = 0,dp[1] = 1;
 8         for(int i=2;i<=n;i++){
 9             dp[i] = dp[i-1]+dp[i-2];
10         }
11         return dp[n];
12     }
13 };
View Code

 70. 爬楼梯 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int climbStairs(int n) {
 4         if(n<=2)
 5             return n;
 6         vector<int> dp(n+1,0);
 7         dp[1] = 1;dp[2] = 2;
 8         for(int i=3;i<=n;i++){
 9             dp[i] = dp[i-1]+dp[i-2];
10         }
11         return dp[n];
12     }
13 };
View Code

 746. 使用最小花费爬楼梯 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int minCostClimbingStairs(vector<int>& cost) {
 4         int n = cost.size();
 5         vector<int>dp(n+1,0);//要到n这里,楼梯0-n-1
 6         for(int i=2;i<=n;i++){
 7             dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
 8         }
 9         return dp[n];
10     }
11 };
View Code

 62. 不同路径 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int uniquePaths(int m, int n) {
 4         vector<vector<int>>dp(m,vector(n,0));
 5         dp[0][0] = 1;
 6         for(int i=0;i<m;i++){
 7             for(int j=0;j<n;j++){
 8                 if(i>0)
 9                 dp[i][j] += dp[i-1][j];
10                 if(j>0)
11                 dp[i][j] += dp[i][j-1];
12             }
13         }
14         return dp[m-1][n-1];
15     }
16 };
View Code

 63. 不同路径 II - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
 4         int m = obstacleGrid.size(),n = obstacleGrid[0].size();
 5         vector<vector<int>> dp(m,vector(n,0));
 6         if(obstacleGrid[0][0]==0)
 7             dp[0][0] = 1;
 8         for(int i=0;i<m;i++){
 9             for(int j=0;j<n;j++){
10                 if(obstacleGrid[i][j]==1)
11                     continue;
12                 if(i>0)
13                     dp[i][j]+=dp[i-1][j];
14                 if(j>0)
15                     dp[i][j]+=dp[i][j-1];
16             }
17         }
18         return dp[m-1][n-1];
19     }
20 };
View Code

 96. 不同的二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int numTrees(int n) {
 4         vector<int> dp(n+1);
 5         dp[0] = 1;
 6         for(int i=1;i<=n;i++){
 7             for(int j=0;j<=i-1;j++){
 8                 dp[i] += dp[j]*dp[i-j-1];
 9             }
10         }
11         return dp[n];
12     }
13 };
14 /*元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量
15 
16 元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量
17 
18 元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量
19 
20 有2个元素的搜索树数量就是dp[2]。
21 
22 有1个元素的搜索树数量就是dp[1]。
23 
24 有0个元素的搜索树数量就是dp[0]。*/
View Code

 494. 目标和 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int findTargetSumWays(vector<int>& nums, int target) {
 4         sort(nums.begin(),nums.end());
 5         int sum = 0;
 6         for (int i = 0; i < nums.size(); i++) 
 7             sum += nums[i];
 8         if(abs(target)>sum)
 9             return 0;
10         if((target+sum)%2==1)
11             return 0;
12         int bagSize = (target + sum) / 2;
13         vector<int>dp(bagSize+1,0);
14         dp[0] = 1;
15         for(int i=0;i<nums.size();i++){
16             for(int j=bagSize;j>=nums[i];j--){
17                 dp[j] = dp[j]+dp[j-nums[i]];
18             }
19         }
20         return dp[bagSize];
21     }
22 };
23 
24 /*
25 既然为target,那么就一定有 left组合 - right组合 = target。
26 
27 left + right等于sum,而sum是固定的。
28 
29 公式来了, left - (sum - left) = target -> left = (target + sum)/2 。
30 */
View Code

 474. 一和零 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int findMaxForm(vector<string>& strs, int m, int n) {
 4         vector<vector<int>> dp(m + 1, vector<int> (n + 1, 0)); // 默认初始化0
 5         for (string str : strs) { // 遍历物品
 6             int oneNum = 0, zeroNum = 0;
 7             for (char c : str) {
 8                 if (c == '0') zeroNum++;
 9                 else oneNum++;
10             }
11             for (int i = m; i >= zeroNum; i--) { // 遍历背包容量且从后向前遍历!
12                 for (int j = n; j >= oneNum; j--) {
13                     dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
14                 }
15             }
16         }
17         return dp[m][n];
18     }
19 };
View Code

 518. 零钱兑换 II - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int change(int amount, vector<int>& coins) {
 4         sort(coins.begin(),coins.end());
 5         vector<int> dp(amount+1,0);
 6         dp[0]=1;
 7         for(int i=0;i<coins.size();i++){
 8             for(int j=coins[i];j<=amount;j++){
 9                 dp[j] = dp[j]+dp[j-coins[i]];
10             }
11         }
12         return dp[amount];
13     }
14 };
View Code

背包排列组合,排列的话内外循环交换即可 

377. 组合总和 Ⅳ - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int combinationSum4(vector<int>& nums, int target) {
 4         sort(nums.begin(),nums.end());
 5         vector<int> dp(target+1,0);
 6         dp[0] = 1;
 7         for(int i=0;i<=target;i++){
 8             for(int j=0;j<nums.size();j++){
 9                 if (i - nums[j] >= 0 && dp[i] < INT_MAX - dp[i - nums[j]])
10                     dp[i] = dp[i]+dp[i-nums[j]];
11             }
12         }
13         return dp[target];
14     }
15 };
View Code

 322. 零钱兑换 - 力扣(LeetCode) (leetcode-cn.com)

初始化意义尽量有

 1 class Solution {
 2 public:
 3     int coinChange(vector<int>& coins, int amount) {
 4         sort(coins.begin(),coins.end());
 5         vector<int> dp(amount+1,0);
 6         dp[0] = 1;
 7         for(int i=1;i<=amount;i++){
 8             for(int j=0;j<coins.size();j++){
 9                 if(i-coins[j]>=0&&dp[i-coins[j]]!=0){
10                     if(dp[i]!=0)
11                         dp[i] = min(dp[i],dp[i-coins[j]]+1);
12                     else
13                         dp[i] = dp[i-coins[j]]+1;
14                 }
15             }
16         }
17         return dp[amount]-1;
18     }
19 };
View Code
 1 class Solution {
 2 public:
 3     int coinChange(vector<int>& coins, int amount) {
 4         sort(coins.begin(),coins.end());
 5         vector<int> dp(amount+1,-1);
 6         dp[0] = 0;
 7         for(int i=1;i<=amount;i++){
 8             for(int j=0;j<coins.size();j++){
 9                 if(i-coins[j]>=0&&dp[i-coins[j]]!=-1){
10                     if(dp[i]!=-1)
11                         dp[i] = min(dp[i],dp[i-coins[j]]+1);
12                     else
13                         dp[i] = dp[i-coins[j]]+1;
14                 }
15             }
16         }
17         return dp[amount];
18     }
19 };
View Code

 279. 完全平方数 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int numSquares(int n) {
 4         vector<int> dp(10001,10000);
 5         for(int i=1;i<=100;i++)
 6             dp[i*i] = 1;
 7         for(int i=1;i<=100;i++){
 8             for(int j=i*i;j<=n;j++){
 9                 dp[j] = min(dp[j],dp[j-i*i]+1);
10             }
11         }
12         return dp[n];
13     }
14 };
View Code

 139. 单词拆分 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     bool wordBreak(string s, vector<string>& wordDict) {
 4         unordered_set<string> wordSet(wordDict.begin(),wordDict.end());
 5         vector<bool> dp(s.size()+1,false);
 6         dp[0] = true;
 7         for(int i=1;i<=s.size();i++){
 8             for(int j=0;j<i;j++){
 9                 if(dp[j]&&wordSet.find(s.substr(j,i-j))!=wordSet.end())
10                     dp[i] = true;
11             }
12         }
13         return dp[s.size()];
14     }
15 };
View Code

 121. 买卖股票的最佳时机 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {
 4         int mn = prices[0],ans = 0;
 5         for(int i=1;i<prices.size();i++){
 6             ans = max(ans,prices[i]-mn);
 7             mn = min(mn,prices[i]);
 8         }
 9         return ans;
10     }
11 };
View Code
 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {
 4         int len = prices.size();
 5         if(len==0) return 0;
 6         vector<vector<int>>dp(len,vector<int>(2));//两个状态,持有和不持有,也可以设置成本和利润吧
 7         dp[0][0] = -prices[0];
 8         dp[0][1] = 0;
 9         for(int i=1;i<len;i++){
10             dp[i][0] = max(dp[i-1][0],-prices[i]);
11             dp[i][1] = max(dp[i-1][1],prices[i]+dp[i-1][0]);
12         }
13         return dp[len-1][1];
14     }
15 };
View Code

 122. 买卖股票的最佳时机 II - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {//示例一二,共同计算方法,第二天卖就行
 4         int ans = 0;
 5         for(int i=1;i<prices.size();i++){
 6             if(prices[i]-prices[i-1]>0)
 7                 ans+=prices[i]-prices[i-1];
 8         }
 9         return ans;
10     }
11 };
View Code
 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {//dp[i]表示当前最大收益
 4         vector<vector<int>> dp(prices.size(),vector<int>(2));//第i天状态,dp[i][0]持有,dp[i][1]不持有
 5         dp[0][0] = -prices[0];
 6         for(int i=1;i<prices.size();i++){
 7             dp[i][0] = max(dp[i-1][0],dp[i-1][1]-prices[i]);
 8             dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i]);
 9         }
10         return dp[prices.size()-1][1];
11     }
12 };
View Code

 123. 买卖股票的最佳时机 III - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {
 4         vector<vector<int>> dp(prices.size(),vector<int>(5,0));
 5         dp[0][0] = 0;
 6         dp[0][1] = -prices[0];
 7         dp[0][2] = 0;
 8         dp[0][3] = -prices[0];
 9         dp[0][4] = 0;
10         for(int i=1;i<prices.size();i++){
11             dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);
12             dp[i][2] = max(dp[i-1][2],dp[i-1][1]+prices[i]);
13             dp[i][3] = max(dp[i-1][3],dp[i-1][2]-prices[i]);
14             dp[i][4] = max(dp[i-1][4],dp[i-1][3]+prices[i]);
15         }
16         return dp[prices.size()-1][4];
17     }
18 };
View Code

 188. 买卖股票的最佳时机 IV - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxProfit(int k, vector<int>& prices) {
 4         if(prices.size()==0)
 5             return 0;
 6         vector<vector<int>> dp(prices.size(),vector<int>(2*k+1,0));
 7         for(int i=1;i<2*k+1;i+=2){
 8             dp[0][i] = -prices[0];
 9         }
10         for(int i=1;i<prices.size();i++){
11             for(int j=1;j<2*k+1;j++){
12                 if(j%2==1)
13                     dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]-prices[i]);
14                 else
15                     dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]+prices[i]);
16             }
17         }
18         return dp[prices.size()-1][2*k];
19     }
20 };
View Code

 309. 最佳买卖股票时机含冷冻期 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {
 4         int n = prices.size();
 5         if (n == 0) return 0;
 6         vector<vector<int>> dp(n, vector<int>(4, 0));
 7         dp[0][0] -= prices[0]; // 持股票
 8         for (int i = 1; i < n; i++) {
 9             dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i]);//持有
10             dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);//非昨天卖出股票
11             dp[i][2] = dp[i - 1][0] + prices[i];//今天卖出股票
12             dp[i][3] = dp[i - 1][2];//昨天卖出股票今天冷冻期!!!不是当前dp[i][2]
13         }
14         return max(dp[n - 1][3],max(dp[n - 1][1], dp[n - 1][2]));
15     }
16 };
View Code

 714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices, int fee) {
 4         vector<vector<int>> dp(prices.size(),vector<int>(2,0));
 5         dp[0][1] = -prices[0];
 6         int mx = INT_MAX;
 7         for(int i=1;i<prices.size();i++){//1表示持有吧,换一换,0表示没有,这样契合1,0本身意思
 8             dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);//卖出时交手续费,收益-手续费与不买不卖作比较
 9             dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);
10         }
11         return dp[prices.size()-1][0];
12     }
13 };
View Code

 300. 最长递增子序列 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int lengthOfLIS(vector<int>& nums) {//时间复杂度两个for,没想到是两个,
 4         vector<vector<int>> dp(nums.size(),vector<int>(2,1));//维护一个当前值,维护一个这一段答案
 5         for(int i=1;i<nums.size();i++){
 6             for(int j=0;j<i;j++){
 7                 if(nums[i]>nums[j]){
 8                     dp[i][0] = max(dp[i][0],dp[j][0]+1);
 9                 }
10                 dp[i][1] = max(dp[i][1],max(dp[i-1][1],dp[i][0]));//和自己比,和前一段答案比,和当前值比
11             }
12             cout<<dp[i][1]<<" ";
13         }
14         return dp[nums.size()-1][1];
15     }
16 };
View Code

674. 最长连续递增序列 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int findLengthOfLCIS(vector<int>& nums) {//还是维护两个值,一个当前子序列长度,一个这一段的答案如1,2,3,1,2
 4         vector<vector<int>> dp(nums.size(),vector<int>(2,1));
 5         for(int i=1;i<nums.size();i++){
 6             if(nums[i]>nums[i-1])
 7                 dp[i][0] = dp[i-1][0]+1;
 8             dp[i][1] = max(dp[i-1][1],dp[i][0]);
 9         }
10         return dp[nums.size()-1][1];
11     }
12 };
View Code

 718. 最长重复子数组 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int findLength(vector<int>& nums1, vector<int>& nums2) {
 4         vector<vector<int>> dp (nums1.size() + 1, vector<int>(nums2.size() + 1, 0));
 5         int result = 0;
 6         for (int i = 1; i <= nums1.size(); i++) {
 7             for (int j = 1; j <= nums2.size(); j++) {
 8                 if (nums1[i - 1] == nums2[j - 1]) {
 9                     dp[i][j] = dp[i - 1][j - 1] + 1;
10                 }
11                 if (dp[i][j] > result) result = dp[i][j];
12             }
13         }
14         return result;
15     }
16 };
View Code

 1143. 最长公共子序列 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int longestCommonSubsequence(string text1, string text2) {
 4         vector<vector<int>> dp(text1.size()+1,vector<int>(text2.size()+1,0));
 5         int ans = 0;
 6         for(int i=1;i<=text1.size();i++){
 7             for(int j=1;j<=text2.size();j++){
 8                 if(text1[i-1]==text2[j-1])
 9                     dp[i][j] = dp[i-1][j-1]+1;
10                 dp[i][j] = max(dp[i][j],max(dp[i-1][j],dp[i][j-1]));
11                 ans = max(ans,dp[i][j]);
12                 cout<<dp[i][j]<<" ";
13             }
14             cout<<endl;
15         }
16         return ans;
17     }
18 };
View Code

 1035. 不相交的线 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {//其实就是遍历从前往后顺序,依次就行
 4         vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
 5         int ans = 0;
 6         for(int i=1;i<=nums1.size();i++){
 7             for(int j=1;j<=nums2.size();j++){
 8                 if(nums1[i-1]==nums2[j-1])
 9                     dp[i][j] = dp[i-1][j-1]+1;
10                 else
11                     dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
12                 ans = max(ans,dp[i][j]);
13             }
14         }
15         return ans;
16     }
17 };
View Code

 392. 判断子序列 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     bool isSubsequence(string s, string t) {
 4         if(s.size()!=0&&t.size()==0)
 5             return false;
 6         vector<vector<int>> dp(s.size()+1,vector<int>(t.size()+1,0));
 7         for(int i=1;i<=s.size();i++)
 8             for(int j=1;j<=t.size();j++){
 9                 if(s[i-1]==t[j-1]){
10                     dp[i][j] = dp[i-1][j-1]+1;
11                 }else
12                     dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
13             }
14         return dp[s.size()][t.size()]==s.size();
15     }
16 };
View Code

 115. 不同的子序列 - 力扣(LeetCode) (leetcode-cn.com)

难理解

 1 class Solution {
 2 public:
 3     int numDistinct(string s, string t) {
 4         vector<vector<uint64_t>> dp(s.size() + 1, vector<uint64_t>(t.size() + 1));
 5         for (int i = 0; i < s.size(); i++) dp[i][0] = 1;
 6         for (int j = 1; j < t.size(); j++) dp[0][j] = 0;
 7         for (int i = 1; i <= s.size(); i++) {
 8             for (int j = 1; j <= t.size(); j++) {
 9                 if (s[i - 1] == t[j - 1]) {
10                     dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
11                 } else {
12                     dp[i][j] = dp[i - 1][j];
13                 }
14             }
15         }
16         return dp[s.size()][t.size()];
17     }
18 };
View Code

 583. 两个字符串的删除操作 - 力扣(LeetCode) (leetcode-cn.com)

同最大子序列

 1 class Solution {
 2 public:
 3     int minDistance(string word1, string word2) {
 4         vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
 5         int ans = 0;
 6         for(int i=1;i<=word1.size();i++){
 7             for(int j=1;j<=word2.size();j++){
 8                 if(word1[i-1]==word2[j-1])
 9                     dp[i][j]=dp[i-1][j-1]+1;
10                 else
11                     dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
12                 ans = max(ans,dp[i][j]);
13             }
14         }
15         return word1.size()-ans+word2.size()-ans;
16     }
17 };
View Code

 72. 编辑距离 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     int minDistance(string word1, string word2) {
 4         if(word1.size()==0||word2.size()==0)
 5             return max(word1.size(),word2.size());
 6         vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
 7         for(int i=1;i<=word1.size();i++){
 8             dp[i][0] = i;
 9         }
10         for(int i=1;i<=word2.size();i++){
11             dp[0][i] = i;
12         }
13         for(int i=1;i<=word1.size();i++){
14             for(int j=1;j<=word2.size();j++){
15                 if(word1[i-1]==word2[j-1])
16                     dp[i][j] = dp[i-1][j-1];
17                 else
18                     dp[i][j] = min(min(dp[i-1][j-1],dp[i-1][j]),dp[i][j-1])+1;
19                 cout<<dp[i][j]<<" ";
20             }
21             cout<<endl;
22         }
23         return dp[word1.size()][word2.size()];
24     }
25 };
View Code

647. 回文子串 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {//这道题例外,dp数组不是维护答案
 2 public:
 3     int countSubstrings(string s) {
 4         vector<vector<bool>> dp(s.size(),vector<bool>(s.size(),false));
 5         for(int i=0;i<s.size();i++){
 6             dp[i][i] = true;
 7         }
 8         int ans = s.size();
 9         for(int i=1;i<s.size();i++){
10             for(int j=0;j<i;j++){
11                 if(s[i]==s[j]){
12                     if(i-j==1){
13                         ans++;
14                         dp[j][i] = true;
15                     }
16                         
17                     else if(dp[j+1][i-1]){
18                             ans++;
19                             dp[j][i] = true;
20                     }
21                 }
22             }
23         }
24         return ans;
25     }
26 };
View Code

 5. 最长回文子串 - 力扣(LeetCode) (leetcode-cn.com)

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
 5         int maxlenth = 0;
 6         int left = 0;
 7         for (int i = s.size() - 1; i >= 0; i--) {
 8             for (int j = i; j < s.size(); j++) {
 9                 if (s[i] == s[j]) {
10                     if (j - i <= 1) { // 情况一 和 情况二
11                         dp[i][j] = j-i+1;
12                     } else if (dp[i + 1][j - 1]) { // 情况三
13                         dp[i][j] = dp[i+1][j-1]+2;
14                     }
15                 }
16                 if (dp[i][j] && j - i + 1 > maxlenth) {
17                     maxlenth = dp[i][j];
18                     left = i;
19                 }
20             }
21 
22         }
23         return s.substr(left, maxlenth);
24     }
25 };
View Code

超时

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         vector<vector<int>> dp(s.size(),vector<int>(s.size(),0));
 5         int ans = 1,l=0,r=0;
 6         for(int i=0;i<s.size();i++){
 7             for(int j=0;j<=i;j++){
 8                 if(s[j]==s[i]){
 9                     if(i-j<=1)
10                         dp[j][i] = i-j+1;
11                     else if(dp[j+1][i-1]!=0){
12                         dp[j][i]=dp[j+1][i-1]+2;
13                     }
14                 }
15                 if(ans<dp[j][i]){
16                     ans = dp[j][i];
17                     l=j;
18                     r=i;
19                 }
20                 cout<<dp[j][i]<<" ";
21             }
22             cout<<endl;
23         }
24         return s.substr(l,ans);
25 
26     }
27 };
View Code

 

posted @ 2022-02-07 12:47  剩下的交给时间就好  阅读(15)  评论(0编辑  收藏  举报