小红书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;
} 

全部评论
想问一下dp[i][1]的定义是,[0,i]区间内存在某个值被替换了,不一定是结尾的i是吧? 还有为什么状态dp[i][1]的状态转移方程不是这个呢? dp[i][1]=max(max(dp[i-1][0]+x,x),max(dp[i-1][1]+nums[i],num[i]) )
点赞 回复 分享
发布于 2023-07-24 16:14 美国
第二题能讲讲思路吗
点赞 回复 分享
发布于 2023-07-24 15:40 福建

相关推荐

评论
6
19
分享

创作者周榜

更多
牛客网
牛客企业服务