5392 分割字符
代码
简单题
class Solution {
public:
int maxScore(string s) {
int N = s.length();
vector<int> dp0,dp1;
dp0.resize(N);
dp1.resize(N);
for(int i =0;i<N;i++)
{
if(i==0)
{
dp0[0] = 0;
dp1[0] = 0;
}
else{
dp0[i] = dp0[i-1];
dp1[i] = dp1[i-1];
}
if(s[i]=='0')
dp0[i] ++;
else dp1[i]++;
}
int maxi = 0;
for(int i=0;i<N-1;i++)
{
if(dp0[i]+(dp1[N-1]-dp1[i])>maxi)
{
maxi = dp0[i]+dp1[N-1]-dp1[i];
}
}
return maxi;
}
};
5393.可获得的最大点数
代码
经典前缀和
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
vector<int> sum;
int N = cardPoints.size();
sum.resize(N+1);
for(int i=0;i<N;i++)
{
sum[i+1] = sum[i] + cardPoints[i];
}
int ans = 0;
for(int i=0;i<=k;i++)
{
int right = N-k+i;
ans = max(ans, sum[N]-sum[right]+sum[i]);
}
return ans;
}
};
5394. 对角线遍历Ⅱ
暴力,复杂度O(n^2)超时
上图思路转载自链接
代码
typedef pair<long long,int> P;
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& nums) {
vector<P> p;
for(int i=0;i<nums.size();i++)
{
for(int j=0;j<nums[i].size();j++)
{
long long val = (long long)(i+j)*(long long)(i+j+1)/2+j+1;
p.push_back(make_pair(val,nums[i][j]));
}
}
sort(p.begin(),p.end());
vector<int> ans;
for(int i=0;i<p.size();i++)
ans.push_back(p[i].second);
return ans;
}
};
5395. 带限制的子序列和
此题很容易想到递推式dp[i] = max(dp[i],dp[i-j]+nums[i],nums[i])(for j=1;j<=k&&i-j>=0),复杂度KN,所以这样做会超时。dp[i] = max(max(dp[i-j])+nums[i],nums[i]),所以其实我们只要知道dp[i-1]~dp[i-k]中的最大值。
所以考虑使用双端队列,队列头是dp[i]~dp[i-k]最大值的下标。
class Solution {
public:
int constrainedSubsetSum(vector<int>& nums, int k) {
int N = nums.size();
vector<int> dp;
dp.resize(N);
dp[0] = nums[0];
int ans = dp[0];
deque<int> st;
st.push_front(0);
for(int i=1;i<N;i++)
{
dp[i] = max(nums[i],nums[i]+dp[st.front()]);
if(i-st.front()==k)
st.pop_front();
while(st.size()&&dp[st.back()]<dp[i]) //保持单调性
st.pop_back();
st.push_back(i);
ans = max(ans,dp[i]);
}
return ans;
}
};
然后呢,还可以用优先队列
class Solution {
public:
int constrainedSubsetSum(vector<int>& nums, int k) {
int N = nums.size();
vector<int> dp;
dp.resize(N);
dp[0] = nums[0];
int ans = dp[0];
priority_queue<pair<int,int> > que;
que.push(make_pair(dp[0],0));
for(int i=1;i<N;i++)
{
dp[i] = max(nums[i],nums[i]+que.top().first);
while(que.size()&&i-que.top().second>=k)
que.pop();
que.push(make_pair(dp[i],i));
ans = max(ans,dp[i]);
}
return ans;
}
};