做题链接手套__牛客网 (nowcoder.com)
题目描述:A想要拿一个左右手颜色相同的手套,现在左右手套分开放置,但现在天黑看不到,问至少要拿多少只手套(左手加右手),才能保证一定能选出一双颜色相同的手套。
输入:n颜色种数(1≤n≤13) 两个长度为n的数组left,right,分别代表每种颜色左右手手套的数量。数据保证左右的手套总数均不超过26,且一定存在至少一种合法方案。
测试用例:
4 , [0,7,1,6] , [1,5,0,6]
返回:10 (解释:可以左手手套取2只,右手手套取8只)
思路:
1、左边至少覆盖所有颜色(对应右边为0时的颜色,要都算在内),右边除了对应左边为0的颜色中至少选择一个。
2、右边至少覆盖所有颜色(对应左边为0时的颜色,要都算在内),左边除了对应右边为0的颜色中至少选择一个。
从两种中选择较少的一个。
代码:
import java.util.*; public class Gloves { public int findMinimum(int n, int[] left, int[] right) { if(n==1){ return 2; } // max 表示覆盖所有颜色的数量 // min 表示左右至少有一种重合颜色的数量 int leftMin = countMin(n,left,right); int rightMin = countMin(n,right,left); int leftMax = countMax(n,left); int rightMax = countMax(n,right); int a = leftMin+rightMax; int b = leftMax+rightMin; return a>b?b:a; } public int countMin(int n, int[] arr, int[] arr1){ int ret = 0; for(int i=0;i<n;i++){ if(arr1[i] == 0){ ret += arr[i]; } } return ret+1; } public int countMax(int n, int[] arr){ int ret = 0; Arrays.sort(arr); int countZero = 0; while(arr[countZero]==0){ countZero++; }//这里的countZero 是计算了Zero的个数,同时也能确定加到哪里结束,到哪里可以加1就行 for(int i=n-1;i>=countZero;i--){ if(i==countZero+1 && countZero+1<n-1){ ret+=1; }else{ ret+=arr[i]; } } return ret; } }
注意事项 :
1. 要注意当只存在一种颜色的时候,左右两边各取一个就行。
2. 要先计算 Min 再计算 Max ,因为Max里面的排序会影响Min的结果。
3. 计算Max,注意是减去除0之外倒数第二小的数字,其他数字和加一,比如 0 1 5 6 的max是 8