小红书7.23笔试
本人是道听途说选手(base不合没投xhs),在牛客上看完题目顺便打一下题目,交流交流
第二题 精华帖子数量
O(n)听说会超时,我的想法是每个区间左端点找到匹配的右端点,二分查找,时间复杂度为O(mlogm),m为1e5,n为1e9,O(mlogm)远低于O(n)
更新:前缀和+滑动窗口可以达到O(m),代码已更新,写了大概思想,可能没太仔细推敲细节
int main(){
int n, m, k;
cin>>n>>m>>k;
vector<vector<int>>interval;
for(int i = 0; i < m; i++){
int l, r;
cin>>l>>r;
interval.push_back(vector<int>{l, r});
}
// 前缀和
vector<int> pre(interval.size()+1, 0);
for(int i = 1; i <= interval.size(); i++){
pre[i] = pre[i-1] + (interval[i-1][1] - interval[i-1][0]);
}
int maxNum = 0;
int r = 0;
for(int i = 0; i < m; i++){
while(r < m){
if(interval[r][0] - interval[i][0] <= k){
r++;
}
else break;
}
int count = pre[r-1] - pre[i];
// cout<<r<<' '<<i<<' '<<count<<endl;
int z = min(interval[r-1][1], interval[i][0] + k) - interval[r-1][0];
count += z;
maxNum = max(count, maxNum);
}
cout<<maxNum<<endl;
}
第三题 最大连续子数组和
dp[i][0]表示不进行替换的最大和
dp[i][1]表示进行替换后的最大和
int Solution(vector<int>&nums, int x){
vector<vector<int>> dp(nums.size(),vector<int>(2,1));
dp[0][0] = nums[0];
dp[0][1] = x;
for(int i=1;i<nums.size();i++){
// 不替换 = 上一个不替换 或 当前 nums[i]
dp[i][0] = max(dp[i-1][0]+nums[i],nums[i]);
// 替换 = 上一个不替换+x 或 x 或 上一个替换+nums[i]
dp[i][1] = max(max(dp[i-1][0]+x,x),dp[i-1][1]+nums[i]);
}
int maxSum = INT_MIN;
for(int i=0;i<nums.size();i++){
if(dp[i][0]>maxSum) maxSum = dp[i][0];
if(dp[i][1]>maxSum) maxSum = dp[i][1];
}
return maxSum;
}