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