9. leetcode(动态规划-子序列问题)

1. leetcode 300 最长递增子序列

class Solution {
    
    
public:
    int lengthOfLIS(vector<int>& nums) {
    
    
        if (nums.size() <= 1) return nums.size();
        int res = 0;
        vector<int> dp(nums.size(), 1);   //初始化为1
        for (int i = 1; i < nums.size(); i++) {
    
       //遍历 数组
            for (int j = 0; j < i; j++) {
    
       //从i之前寻找比nums[i] 小的数
                if (nums[i] > nums[j]) {
    
    
                    dp[i] = max(dp[i], dp[j] + 1); 
                }
            }
            if (dp[i] > res) res = dp[i];  //比较 取最长的子序列
        }
        return res;
    }
};

2. leetcode 674 最长连续递增序列

//滑动窗口
class Solution {
    
    
public:
    int findLengthOfLCIS(vector<int>& nums) {
    
    
        int last = 0; //设定一个头指针
        int res = 1;  //初始化结果
        for (int i = 1; i < nums.size(); i++) {
    
    
            if (nums[i - 1] < nums[i]) {
    
    
                res = max(res, i - last + 1);
            } else {
    
    
                last = i;
            }
        }
        return res;
    }
};

//动态规划
class Solution {
    
    
public:
    int findLengthOfLCIS(vector<int>& nums) {
    
    
        if (nums.size() == 0) return 0;
        int result = 1;
        vector<int> dp(nums.size(), 1);
        for (int i = 0; i < nums.size() - 1; i++) {
    
    
            if (nums[i + 1] > nums[i]) {
    
    
                dp[i + 1] = dp[i] + 1;
            }
            if (dp[i + 1] > result) result = dp[i + 1];
        }
        return result;
    }
};

//贪心

class Solution {
    
    
public:
    int findLengthOfLCIS(vector<int>& nums) {
    
    
        if (nums.size() == 0) return 0;
        int res = 1;
        int count = 1;
        for (int i = 0; i < nums.size() - 1; i++) {
    
    
            if (nums[i + 1] > nums[i]) {
    
      // 连续记录
                count++;
            } else {
    
       //不连续,从头开始
                count = 1;  
            }
            if (count > res) res = count;
        }
        return res;
    }
};

3. leetcode 718 最长重复子数组

//动态规划
class Solution {
    
    
public:
    int findLength(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;
                }
                if (dp[i][j] > result) result = dp[i][j];
            }
        }
        return result;
    }
};


//滚动数组
//遍历B数组的时候,就要从后向前遍历,这样避免重复覆盖

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

4. leetcode 1143 最长公共子序列

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()];
    }
};

5. leetcode 1035 不相交的线

//与最长公共子序列相同

class Solution {
    
    
public:
    int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
    
    
        vector<vector<int>> dp(nums1.size() + 1, vector<int>(nums2.size() + 1, 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]);
                }
            }
        }
        return dp[nums1.size()][nums2.size()];
    }
};

6. leetcode 53 最大子数组和

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

7. leetcode 392 判断子序列


class Solution {
    
    
public:
    bool isSubsequence(string s, string t) {
    
    
        vector<vector<int>> dp(s.size() + 1, vector<int>(t.size() + 1, 0));
        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] + 1;
                } else {
    
    
                    dp[i][j] = dp[i][j - 1];
                }
            }            
        }
        if (dp[s.size()][t.size()] == s.size()) return true;
        return false;

    }
};

8. leetcode 115 不同的子序列

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

9. leetcode 583 两个字符串的删除操作

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

10. leetcode 72 编辑距离

class Solution {
    
    
public:
    int minDistance(string word1, string word2) {
    
    
        vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1, 0));
        for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
        for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;

        for (int i = 1; i <= word1.size(); i++) {
    
    
            for (int j = 1; j <= word2.size(); j++) {
    
    
                if (word1[i - 1] == word2[j - 1]) {
    
    
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
    
    
                    dp[i][j] = min({
    
    dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]}) + 1;
                }
            }
        }
        return dp[word1.size()][word2.size()];
    }
};

11. leetcode 647 回文子串


class Solution {
    
    
public:
    int countSubstrings(string s) {
    
    
        vector<vector<bool>> dp(s.size(), vector<bool>(s.size(), false));
        int result = 0;
        for (int i = s.size() - 1; i >= 0; i--) {
    
    
            for(int j = i; j < s.size(); j++) {
    
    
                if (s[i] == s[j]) {
    
    
                    if (j - i <= 1) {
    
      // 情况一
                        result++;
                        dp[i][j] = true;
                    } else if (dp[i + 1][j - 1]) {
    
      // 情况三
                        result++;
                        dp[i][j] = true;
                    }
                }
            }
        }
        return result;
    }
};

// 双指针法

class Solution {
    
    
public:
    int countSubstrings(string s) {
    
    
        int result = 0;
        for (int i  =0; i < s.size(); i++) {
    
    
            result += extend(s, i, i, s.size());
            result += extend(s, i, i + 1, s.size());
        }
        return result;
    }

    int extend(const string& s, int i, int j, int n) {
    
    
        int res = 0;
        while (i >= 0 && j < n && s[i] == s[j]) {
    
    
            i--;
            j++;
            res++;
        }
        return res;
    }
};

12. leetcode 516 最长回文子序列

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];
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_44847326/article/details/123717882