代码随想录第五十二天、第五十三天、第五十五天、第五十六天、第五十七天|子序列问题

代码随想录第五十二天|子序列问题

  • Leetcode300.最长递增子序列
  • Leetcode674. 最长连续递增序列
  • Leetcode718. 最长重复子数组
    • 二刷标记
  • Leetcode1143. 最长公共子序列
  • Leetcode1035. 不相交的线
  • Leetcode53. 最大子数组和
  • Leetcode392.判断子序列
  • Leetcode115.不同的子序列
  • Leetcode647. 回文子串
  • Leetcode516.最长回文子序列

Leetcode300.最长递增子序列

题目链接:300.最长递增子序列
还是分析清楚dp数组含义和递推公式的问题,第一遍没做出来这个就是因为:1.没想清楚dp数组下标含义,2。没推明白递推公式

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if(nums.size()==1) return 1;
        vector<int> dp(nums.size(),1);
        int result=0;
        for(int i=1;i<nums.size();i++){
            for(int j=0;j<i;j++){
                if(nums[i]>nums[j]) dp[i]=max(dp[i],dp[j]+1);
            }
            result=max(result,dp[i]);
        }
        return result;
    }
};

Leetcode674. 最长连续递增序列

题目链接:674. 最长连续递增序列
太简单了,根本不需要动归,浪费空间

class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        if(nums.size()==1) return 1;
        int result=1,tmp=1,start=nums[0],end=nums[0];
        for(int i=0;i<nums.size();i++){
            if(nums[i]<=end){
                start=nums[i];
                end=nums[i];
                tmp=1;
            }
            else{
                end=nums[i];
                tmp++;
            }
            result=max(result,tmp);
        }
        return result;
    }
};

Leetcode718. 最长重复子数组

题目链接;Leetcode718. 最长重复子数组
这道题值得二刷,还是有一定难度的。

二刷标记

class Solution {
public:
    int findLength(vector<int>& nums1, vector<int>& nums2) {
        if(nums1.size()==1 || nums2.size()==1) return 1;
        vector<vector<int>> dp(nums1.size(),vector<int>(nums2.size(),0));
        int result=0;
        for (int i = 0; i < nums1.size(); i++) if (nums1[i] == nums2[0]) dp[i][0] = 1;
        for (int j = 0; j < nums2.size(); j++) if (nums1[0] == nums2[j]) dp[0][j] = 1;
        for(int i=0;i<nums1.size();i++){
            for(int j=0;j<nums2.size();j++){
                if(i>=1 && j>=1 && nums1[i]==nums2[j]) dp[i][j]=dp[i-1][j-1]+1;
                result=max(result,dp[i][j]);
            }           
        }
        return result;
    }
};

Leetcode1143. 最长公共子序列

题目链接:Leetcode1143. 最长公共子序列
这题复制粘贴的答案,递推公式部分没想明白。
这里有个小技巧,把dp[i][j]定义为长度i长度j使用起来更方便一些,省的初始化0那一排了。

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));
        for (int i = 1; i <= text1.size(); i++) {
            for (int j = 1; j <= text2.size(); j++) {
                if (text1[i - 1] == text2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[text1.size()][text2.size()];
    }
};

Leetcode1035. 不相交的线

题目链接:Leetcode1035. 不相交的线
跟上道题一模一样

class Solution {
public:
    int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
        vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
        int result=0;
        for(int i=1;i<=nums1.size();i++){
            for(int j=1;j<=nums2.size();j++){
                if(nums1[i-1]==nums2[j-1]) dp[i][j]=dp[i-1][j-1]+1;
                else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                result=max(result,dp[i][j]);
            }
        }
        return result;
    }
};

Leetcode53. 最大子数组和

题目链接:Leetcode53. 最大子数组和
用dp反而浪费,用贪心就可以了。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if(nums.size()==1) return nums[0];
        vector<int> dp(nums.size(),0);
        dp[0]=nums[0];
        int result=dp[0];
        for(int i=1;i<nums.size();i++){
            if(dp[i-1]<0) dp[i]=nums[i];
            else dp[i]=dp[i-1]+nums[i];
            result=max(result,dp[i]);
        }
        return result;
    }
};

Leetcode392.判断子序列

题目链接:Leetcode392.判断子序列
只能说不愧是简单题,确实简单,根本用不到dp

class Solution {
public:
    bool isSubsequence(string s, string t) {
        int indexS=0;
        for(int indexT=0;indexT<t.size();indexT++){
            if(indexS==s.size()) return true;
            if(s[indexS]==t[indexT]){
                indexS++;
            }
        }
        return indexS==s.size();
    }
};

Leetcode115.不同的子序列

题目链接:Leetcode115.不同的子序列

class Solution {
public:
    int numDistinct(string s, string t) {
        vector<vector<uint64_t>> dp(s.size()+1,vector<uint64_t>(t.size()+1,0));
        for(int i=0;i<=s.size();i++) dp[i][0]=1;
        for(int i=1;i<=s.size();i++){
            for(int j=1;j<=t.size();j++){
                if(s[i-1]==t[j-1]) dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
                else dp[i][j]=dp[i-1][j];
            }
        }
        return dp[s.size()][t.size()];
    }
};

Leetcode647. 回文子串

题目链接:Leetcode647. 回文子串
转换思路,别总想着以i结尾的数量,想想以i为中心,或以i和i+1为中心

class Solution {
private:
    int extend(string& s,int left,int right){
        int n=s.size(),res=0;
        while(left>=0 && right<n && s[left]==s[right]){
            left--;
            right++;
            res++;
        }
        return res;
    }
public:
    int countSubstrings(string s) {
        int result=0;
        for(int i=0;i<s.size();i++){
             result+=extend(s,i,i);//以i为中心向两边
             result+=extend(s,i,i+1);//以i和i+1为中心向两边
        }
        return result;
    }
};

Leetcode516.最长回文子序列

题目链接:Leetcode516.最长回文子序列

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        vector<vector<int>> dp(s.size(), vector<int>(s.size(), 0));
        for (int i = 0; i < s.size(); i++) dp[i][i] = 1;
        for (int i = s.size() - 1; i >= 0; i--) {
            for (int j = i + 1; j < s.size(); j++) {
                if (s[i] == s[j]) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[0][s.size() - 1];
    }
};

你可能感兴趣的:(leetcode,算法,动态规划)