思路 : 因为牌的面值只有13种可能,所以我们可以创建一个整性数组,然后直接遍历所有牌子,然后对相应牌数的索引自增,就可以得到每种牌面值的数量了。这里用到桶排序的方法:【算法】桶排序(Bucket Sort)详解-CSDN博客 然后我们就可以直接对数组操作了。
import java.util.Arrays;
public class 寻找最大葫芦 {
public static int[] solution(int n, int max, int[] array) {
int[] res;
int[] bucket=new int[14];
for (int i = 0; i < n; i++) {
bucket[array[i]]++;
}
System.out.println(Arrays.toString(bucket));
//有1先选1,因为这里1是最大的!
if(bucket[1]>2){
int j=13;
//第二个也选最大的,如果大于阈值就往下减小
while(j>1){
//越界就没有符合的情况因为1和其他组合都是比较小的,没越界就是合法的直接返回
if(bucket[j]>1&&(2*j+3)<max){
res=new int[]{1, j};
System.out.println(Arrays.toString(res));
return res;
}
j--;
}
}
//没有1的就需要逐个试一下,先选最大的
int i2=0,j3=13,two=0;
while(j3>1){
//这里也是先处理1的情况,因为1是大的
if(bucket[j3]>2&&bucket[1]>1&&(2+3*j3)<=max){
res=new int[]{j3,1};
return res;
}
i2=2;
two=14;
if(bucket[j3]>2){
while(i2<14){
if((3*j3+2*i2)<=max&&bucket[i2]>1&&j3!=i2){
two=i2;
}
i2++;
}
if(two<14){
res=new int[]{j3,two};
System.out.println(Arrays.toString(res));
return res;
}
}
j3--;
}
res= new int[]{0, 0};
System.out.println(Arrays.toString(res));
return res;
}
public static void main(String[] args) {
// Add your test cases here
System.out.println(java.util.Arrays.equals(solution(9, 34, new int[]{6, 6, 6, 8, 8, 8, 5, 5, 1}), new int[]{8, 5}));
System.out.println(java.util.Arrays.equals(solution(9, 37, new int[]{9, 9, 9, 9, 6, 6, 6, 6, 13}), new int[]{6, 9}));
System.out.println(java.util.Arrays.equals(solution(9, 40, new int[]{1, 11, 13, 12, 7, 8, 11, 5, 6}), new int[]{0, 0}));
}
}
代码的主要逻辑如下:
- 初始化一个长度为14的数组
bucket,用于记录每种牌面值出现的次数。 - 遍历输入的牌数组
array,统计每种牌面值的出现频率,并存储在bucket数组中。 - 首先检查是否存在牌面值为1的牌(因为1是最大的牌面值),如果存在三张或以上,尝试找到与之配对的最大牌面值,使得两者之和不超过
max。如果找到合适的配对,则返回这个组合。 - 如果没有三张或以上的1,或者没有合适的配对,则遍历其他牌面值,尝试找到两个不同的牌面值,它们的出现次数都大于1,并且组合后的牌面值之和不超过
max。在这个过程中,优先考虑牌面值较大的组合。在这种没有三张1可以选的情况下,如果1的数量是2张,那么两张的1需要被优选选出来。 - 如果找到符合条件的组合,则返回这个组合。如果没有找到,则返回“0, 0”。