最大子数组和
问题描述
返回给定数组中的最大子数组和。
思路
用贪心会超时。
动态规划的思路
具体实现
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()];
}
};
浙公网安备 33010602011771号