链接:https://www.nowcoder.com/questionTerminal/365d5722fff640a0b6684391153e58d8
来源:牛客网
在地下室里放着n种颜色的手套,手套分左右手,但是每种颜色的左右手手套个数不一定相同。A先生现在要出门,所以他要去地下室选手套。但是昏暗的灯光让他无法分辨手套的颜色,只能分辨出左右手。所以他会多拿一些手套,然后选出一双颜色相同的左右手手套。现在的问题是,他至少要拿多少只手套(左手加右手),才能保证一定能选出一双颜色相同的手套。
思路:
比如给两个颜色left:【3,2】和right:【2,4】
那么只要计算左手数之和sum,再减去左手中颜色数量最少的手套并加1,这样就能保证以这个数量无论什么情况都能拿到左手中所有的颜色;3+2- 2+1=4
右手同理 2+4 -2+1 =5
然后求取能覆盖左手或能覆盖右手所有颜色的最小手套数量,这样另一只手只要随便取一个便可以满足条件;min(4,5)+1=5就是上面的答案;
这是最简单的例子,然后还需要考虑例子中有0的情况;比如:
vector left{ 0, 3, 1, 0, 2, 0, 2 };
vector right{ 3, 2, 1, 4, 0, 4, 1 };
这里可以这么理解:
可分为两部分计算:
1.对于left或ringht为0的颜色,用最小数量覆盖一只手的所有颜色时要把这部分加上,然后,之前左右手不为0处理另一只手是直接加1,现在也必须把不为0的那一部分加上才能满足条件。 所以最终数量都要把0对应的另一只手的数量加上;
2.对于left和right都不为0的按照之前的方法计算即可;
int findMinimum(int n, vector<int> left, vector<int> right) {
int num = 0;
int leftmin = INT_MAX;
int rightmin = INT_MAX;
int leftsum = 0;
int rightsum = 0;
for (int i = 0; i < n; i++) {
if (left[i] == 0||right[i]==0) {
num += left[i];
num += right[i];
}
else {
leftmin = min(leftmin, left[i]);
rightmin = min(rightmin, right[i]);
leftsum += left[i];
rightsum += right[i];
}
}
int a = min(leftsum- leftmin + 1, rightsum - rightmin + 1);
num += (a + 1);
return num;
}
int main()
{
//vector<int> left{ 1, 2, 0, 1, 3, 1 };
//vector<int> right{ 0, 0, 0, 2, 0, 1 };
vector<int> left{ 0, 3, 1, 0, 2, 0, 2 };
vector<int> right{ 3, 2, 1, 4, 0, 4, 1 };
int n = left.size();
cout << findMinimum(n,left,right) << endl;
}