动态规划
一、最长递增子序列
非连续,需要两层循环,用来从[0, i-1]与i进行比较
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
//动态规划
//dp[i]表示遍历到i时最长长度
if (nums.size() <= 1) return nums.size();
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);
}
if (dp[i] > result) result = dp[i];
}
return result;
}
};
二、 最长连续递增序列
贪心比较简单,连续,如果大于则加一,否则置为1重新开始
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
//
int count = 1;
int result = 1;
for (int i = 1; i < nums.size(); i++) {
if (nums[i] > nums[i-1]) {
count++;
result = max (result, count);
}
else {
count = 1;
}
}
return result;
}
};
三、 最长重复子数组
暴力解法,两层循环
动态规划,当前状态由前一个节点推出
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 = 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 (nums1[i] == nums2[j] && i > 0 && j > 0) { // 防止 i-1 出现负数
dp[i][j] = dp[i - 1][j - 1] + 1;
}
if (dp[i][j] > result) result = dp[i][j];
}
}
return result;
}
};
总结
学习时间90min。
学习资料:《代码随想录》。