大厂笔试汇总
大厂笔试汇总
1.交易系统的降级策略
题目描述:有一个核心交易系统接口被N个上游系统调用,每个上游系统的调用量R=[R1,R2…,RN].由于核心交易系统集群故障,需要暂时系统降级限制调用,核心交易系统能接受的最大调用量为cnt。设置降级规则如下;如果sum(R1.R2…RN)小于等于cnt,则全部可以正常调用,返回-1;如果sum(R1.R2…RN)大于cnt,设置一个闻值limit,如果某个上游系统发起的调用量超过limt,就将该上游系统的调用量限制为limit,其余未达到limit的系统可以正常发起调用。求出这个最大的limit(limit可以为0)此题目对效率有要求,请选择高效的方式。
输入描述
第一行:每个上游系统的调用量(整型数组) 第二行:核心交易系统的最大调用量 0<R.length<=10^5,0<R[i]<105,0<cnt <= 10^9
输出描述
调用量的阈值Iimit
测试用例
样例1: 输入: 1 4 2 5 5 1 6 13 输出: 2 解释:因为1+4+2+5+5+1+6>13;将limit设置为2,则1+2+2+2+2+1+2=12<13。所以imit为2 样例2: 输入: 1 7 8 8 1 0 2 4 9 7 输出: 0 解释:因为即使limit设置为1,1+1+1+1+1+1+1+1=8>7也不满足,所以limit只能为0
解题思路:二分法,在[0, end]左闭右闭区间内不断搜索符合条件的limit,本题需要搜索到符合条件的最大右边界,即找到ret恰好小于cnt时对应的end边界。这就需要在区间内寻找符合条件的右边界相关算法,在后面已经引入。
#include <iostream>
#include <vector>
using namespace std;
int getSum(vector<int>& nums, int limit)
{
int sum = 0;
for(int num : nums)
{
if(num < limit) sum += num;
else sum += limit;
}
return sum;
}
int getLimit(vector<int>& nums, int cnt, int begin, int end)
{
// 二分法实现 寻找符合条件的右边界(因为要找到ret恰好小于cnt时对应的边界)
int mid = 0;
while(begin < end)
{
mid = begin + (end - begin) / 2;
int ret = getSum(nums, mid);
// 需要缩小左侧边界
if(ret < cnt)
{
begin = mid + 1;
}
// 需要缩小右侧边界
else if(ret > cnt)
{
end = mid - 1;
}
else
{
// 别返回,收缩右侧边界
begin = mid + 1;
}
}
// 返回ret恰好小于cnt时对应的mid,即我们需要的limit
return end;
}
int main() {
// vector<int> nums{1,7,8,8,1,0,2,4,9};
// int cnt = 7;
vector<int> nums{
2,4,2,5,5,2,6};
int cnt = 1;
int sum = 0;
int begin =