1035.不相交的线:
在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。
现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足:
nums1[i] == nums2[j]
且绘制的直线不与任何其他连线(非水平线)相交。
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。以这种方法绘制线条,并返回可以绘制的最大连线数。
思路:和最长公共子序列是一样的,由图可见1 4 就是两个数组的最长公共子序列。
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 res=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()];
}
};
53.最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组
是数组中的一个连续部分。
思路:1.贪心法:局部最优推出全局最优,局部最优就是当前两个的和大于0,如果两个和小于0时,将sum重置为0。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
//1.贪心做法
//局部最优推出 全局最优
vector<int> res(nums.size()+1);
int j=1,i=0;
int sum=0;
int count=-INT_MAX;
for(int i=0;i<nums.size();i++){
sum+=nums[i];
count=max(sum,count);
if(sum<0){
sum=0;
}
}
return count;
}
};
2.动态规划:
思路:定义一个dp数组,这道题目的核心就在于推出递归公式,dp[i]意义在于包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]。dp[i]由什么可以推导出来呢,dp[i]取 当前数组的值或者加上当前数组的值 的最大值。定义一个res来取整个数组的最大值。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
//2.动态规划
if(nums.size()==0)
return 0;
vector<int> dp(nums.size()+1);
//dp数组的含义是 dp[i] 代表 0-i 区间的 最大子数组和
dp[0]=nums[0];
int res=dp[0];
//dp[i]=dp[i-1]+nums[i];
for(int i=1;i<nums.size();i++){
dp[i]=max(nums[i],dp[i-1]+nums[i]);
res=max(res,dp[i]);
}
return res;
}
};
392.判断子序列
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
致谢:
特别感谢 @pbrother 添加此问题并且创建所有测试用例。
思路:1.双指针做法,遇到相同的就移动指向字串的指针,当slow等于字串长度时,返回true,否则返回false。
class Solution {
public:
bool isSubsequence(string s, string t) {
if(s.size()==0){
return true;
}
int slow=0;
int fast=0;
for(slow,fast;fast<t.size();fast++){
if(s[slow]==t[fast])
{
slow++;
if(slow==s.size()){
return true;
}
}
}
return false;
}
};
2.动态规划:
思路: 和最长公共子序列也是蛮像的,不过else的语句里只有dp[i][j-1],没有dp[i-1][j],因为s是子串,不能用子串来判断。 注意 i和j可以等于是,s,size和t.size() 因为 让i可以等于s.size()是为了完整地检查s是否是t的子序列,确保考虑到了s的所有字符与t的不同部分进行匹配的情况。
class Solution {
public:
bool isSubsequence(string s, string t) {
vector<vector<int>> dp(s.size()+1,vector<int>(t.size()+1,0));
if (s.empty()) return true;
if (t.empty()) return false;
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;
}
};