解题核心思路:贪心算法
对于这个题要考虑的核心问题是要保证其中一只手能够拿到全部颜色的手套,对此,我们做如下推断:要想保证一只手能够拿到全部颜色,我们需要将一双手的手套总数相加,减去数量最少的颜色,再加一,这样我们就能保证这只手所拿到的颜色涵盖了它原有的颜色。
题目所述要保证“至少”的问题,因此,我们需要对左右手的数量进行判断,尽可能的从数量少的一只手里保障取到所有颜色,此时我们先不考虑为零的情况,对总数少的一方进行相加,求出保证全部颜色能拿到的最小结果。
将上述的0先替换为2
则N=(4+6+2+1+3+2)-1+1,即N=18。
此时我们在第一只手中任取一只即可与第二只手中的其中一只组成一对。即第一只手取一只,第二只手取18只,即可求解~
对于存在零的情况我们如何进行求解?
我们可以做以下处理:
我们可以对存在0的颜色单独处理,不进行总数相加的考虑范围,即先排除0的情况进行考虑,此时得到N=(4+6+1+3)-1+1=14只,这样一来,保证从右手的这四个颜色都包含,左手取任意一只这四个颜色中的一个都可以进行匹配。接下来考虑为零的情况,如果左手恰好去了五只都是蓝色,那岂不是没得配对的?因此左右最起码要拿6只才能保证必有一对颜色匹配的手套。此时我们右手的黑色手套并没有考虑,假如从右手拿的14只手套中包含了两只黑色的,少了一只紫色和粉色的,恰好此时左手除了拿了五个蓝色的之外刚好拿了一个紫色的呢?那就又匹配失败,对此,我们只能对右手的两只黑色手套进行相加取出。至此即可保证左右手必有一对匹配的。
总结:贪心体现在先对总体除去0以外进行相加,对比左右手个数,从个数少的中取,最后再对颜色为0的进行逐个相加,求解即为最优解~
代码如下:
public class Main {
public static void main(String[] args) {
int num = 6;
int[] arr1 = {2,4,5,3,6,0};
int[] arr2 = {4,6,0,1,3,2};
int ret = findMinimum(num,arr1,arr2);
System.out.println(ret);
}
public static int findMinimum(int n, int[] left, int[] right) {
int count = 0;
int left_sum = 0;
int right_sum = 0;
int left_min = Integer.MAX_VALUE;
int right_min = Integer.MAX_VALUE;
int sum = 0;
for (int i = 0; i < n; i++) {
if(left[i] * right[i] == 0){//说明某颜色某只手没拿到
sum = sum + right[i] + left[i];
}else {
left_sum = left_sum + left[i];
right_sum = right_sum + right[i];
left_min = Math.min(left_min,left[i]);
right_min = Math.min(right_min,right[i]);
}
}
System.out.println("left_sum=" + left_sum);
System.out.println("left_min=" + left_min);
System.out.println("right_sum=" + right_sum);
System.out.println("right_min=" + right_min);
count = sum + Math.min(left_sum - left_min + 1,right_sum - right_min + 1) + 1;
return count;
}
}
结果如下:左手拿6只,右手拿16只~