最大子数组和

问题描述

返回给定数组中的最大子数组和。

思路

用贪心会超时。
动态规划的思路

具体实现

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        if (nums.size()==0) return 0;
        vector<int>dp(nums.size()+1,0);
        dp[0]=nums[0];
        int result=dp[0];
        for(int i=1;i<nums.size();i++){
            dp[i]=max(dp[i-1]+nums[i],nums[i]);
            if(dp[i]>result) result=dp[i];
        }
        return result ;
        //贪心实现:
        // int sum;
        // int result = INT_MIN;
        // for (int i = 0; i < nums.size(); i++) {
        //     sum = 0;
        //     for (int j = i; j < nums.size(); j++) {
        //         sum += nums[j];
        //         result = sum > result ? sum : result;
        //     }
        // }
        // return result;
    }
};

小结

动态规划的思路直观且清晰,以至于已经不理解贪心的思路了。

判断子序列

题目理解

给出两个字符串,判断s是否是t的字串。

具体实现

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

不同的子序列

代码实现

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

两个字符串的删除操作

问题描述

给定两个单词,找到能使word1=word2的最小操作步数。给定案例中不包含有字母顺序捕相同的情况,暂且默认两个单词中字母的顺序是一致的。需要对两个单词进行处理:找到最大公因子,删除多余的。

class Solution {
public:
    int minDistance(string word1, string word2) {
        vector<vector<int>> dp(word1.size() + 1,
                               vector<int>(word2.size() + 1, 0));
        if (word1.size() == 0 || word2.size() == 0)
            return 0;
        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] + 1;
                } else
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
        return word1.size()+word2.size()-dp[word1.size()][word2.size()]*2;
    }   
};

编辑距离

题目理解

给定两个单词word1和word2, 返回将word1转换成word2所使用的最小操作数。可以进行插入,删除和替换。
题目中没有明确两个单词的大顺序是否一样。hello和olleh 但是示例中两个单词的大顺序是一样的,暂且按照整体的顺序是一致地进行处理。intention和tionexecut,不存在交换,所以不需要考虑顺序。理论上来说,这个数一定是小于word1+word2.为什么不能用上一道题:两个字符串的删除操作呢,给定两个字符串,找到能使word1=word2的最小操作数。???

实现

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(min(dp[i - 1][j]+1, dp[i][j - 1]+1),dp[i - 1][j - 1] + 1);
            }
        }
        return dp[word1.size()][word2.size()];
    }
};
posted on 2025-12-21 22:26  FAfa_C++  阅读(0)  评论(0)    收藏  举报