数组选k元素最大和问题:每次选元素需弃左右一侧,求证解法正确性
面试问题:选取k个元素的最大和
给定数组(例如[4, 6, -10, -1, 10, -20])和数值k(例如4),需从数组中选取k个元素,要求每次选取一个元素后,必须丢弃该元素的左侧所有元素或右侧所有元素,最终返回k个元素的最大和(示例输出为19,即4+6+-1+10)。
注:数组元素数量n≤10^5,k≤n。
我的解法思路
采用双向遍历(从左到右再从右到左)的策略:
- 从左到右遍历时,用
multiset维护一个滑动窗口,窗口内的元素最多保留k个;当窗口大小超过k时,移除窗口中的最小元素,同时跟踪当前窗口元素的最大和; - 反转数组后,重复上述遍历逻辑;
- 最终返回两次遍历得到的最大和中的较大值。
实现代码
#include<bits/stdc++.h> using namespace std; long helper(vector<int>&nums, int k) { multiset<long> st; long sum=0l, res=LONG_MIN; for(int j=0; j<nums.size(); j++) { sum+=nums[j]; st.insert(nums[j]); if(j<k-1) continue; while(st.size()>k) { sum-=*st.begin(); st.erase(st.begin()); } res=max(res, sum); } return res; } long solution(vector<int>&nums, int k){ long res1=helper(nums, k); reverse(begin(nums), end(nums)); long res2=helper(nums, k); return max(res1, res2); } int main() { vector<int> nums={-5,4,-10,-1,-5,8,-3}; cout<<solution(nums, 3)<<endl; nums={4,4,4,4,4}; cout<<solution(nums, 4)<<endl; return 0; }
测试验证
我在多个测试用例上验证过代码,返回结果均符合预期。
示例选取逻辑说明
对于数组[4, 6, -10, -1, 10, -20],选取步骤如下:
- a. 首先选取10并丢弃其右侧的-20;
- b. 接下来选取4并丢弃其左侧元素(无),剩余数组为
[6, -10, -1]; - c. 然后选取6并丢弃其左侧元素(无),剩余数组为
[-10, -1]; - d. 最后选取-1。
请问我的解法是否正确?
内容的提问来源于stack exchange,提问作者Someone
相关产品推荐
相关产品推荐

