问题描述
我正在尝试从多个数组列表中选择一个数字,并找到所有可能的方法来选择这些数字,以使这些数字的总和大于给定的数字。我只能想到蛮力实现。
例如,我有五个数组列表如
A = [2,6,7]
B = [6,9]
C = [4]
D = [4,7]
E = [8,10,15]
并且给定的数字是 40。 然后从每个列表中选择一个数字后,所有可能的方式都可以
[7,9,4,7,15]
[6,15]
因此,这是选择大于或等于 40 的数字的两种可能方法。如果给定的数字很小,则可能有很多解决方案。那么我如何在没有蛮力的情况下计算它们呢?即使使用蛮力,我如何在 Java 中设计解决方案。
下面是我的实现。它适用于小数字,但如果数字很大,那么它会给我带来运行时错误,因为程序运行时间过长。
public static void numberOfWays(List<Integer> A,List<Integer> B,List<Integer> C,List<Integer> D,List<Integer> E,int k){
long ways = 0;
for(Integer a:A){
for(Integer b:B){
for(Integer c:C){
for(Integer d:D){
for(Integer e:E){
int sum = a+b+c+d+e;
//System.out.println(a+" "+b+" "+c+" "+d+" "+e+" "+sum);
if(sum > k)
ways++;
}
}
}
}
}
System.out.println(ways);
}
列表最多可以包含 1000 个元素,元素的范围可以从 1 到 1000。阈值 k 的范围可以从 1 到 10^9。
解决方法
一种方法是这样。必须至少有一个解决方案,您可以从每个数组中选择一个数字并将它们相加以大于或等于另一个。
考虑到数组可能有任意顺序的随机数,首先使用这个排序函数将它们按降序排列(最大数在前,最小数在后):
Arrays.sort(<array name>,Collections.reverseOrder());
然后选择数组中的第一个元素:
v = A[0]
w = B[0]
x = C[0]
y = D[0]
z = E[0]
然后你可以像这样打印它们:v,w,x,y,z
现在您的输出将是:
7,9,4,7,15
由于每个数组取了最大的数,所以它必须等于或大于给定的数,除非该数大于所有这些的总和,在这种情况下是不可能的。
编辑:我想我的问题错了。如果您想知道有多少可能的解决方案,那就容易多了。
首先创建一个变量来存储可能性
var total = 0
使用rand函数得到一个随机数。在你的数组中说:
v=A[Math.random(0,A[].length)]
对所有数组做同样的事情,然后将它们相加
var sum = v+w+x+y+z
现在您有一个 if 语句来查看总和是否大于或等于给定的数字(假设该值存储在变量“given”中)
if(sum >= given){
total+=1
}else{
<repeat the random function to restart the process and generate a new sum>
}
最后,您需要多次重复此操作,因为如果有多种解决方案,则代码只会找到一个并给您一个错误的总数。
要解决这个问题,请创建一个 for 循环并将所有这些代码放入其中:
//create a variable outside to store the total number of elements in all the arrays
var elements = A[].length + B[].length + C[].length + D[].length + E[].length
for(var i = 0; i <= elements; i++){
<The code is inside here,except for "total" as otherwise the value will keep resetting>
}
最终结果应该是这样的:
var total = 0
var elements = A[].length + B[].length + C[].length + D[].length + E[].length
for(var i = 0; i <= elements; i++){
v=A[Math.random(0,A[].length)]
w=B[Math.random(0,B[].length)]
x=C[Math.random(0,C[].length)]
y=D[Math.random(0,D[].length)]
z=E[Math.random(0,E[].length)]
var sum = v+w+x+y+z
if(sum >= given){
total+=1
}else{
v=A[Math.random(0,A[].length)]
w=B[Math.random(0,B[].length)]
x=C[Math.random(0,C[].length)]
y=D[Math.random(0,D[].length)]
z=E[Math.random(0,E[].length)]
}
}
最后在整个周期结束后打印总数或只是做
console.log(total)
这仅供参考,代码可能无法工作,它可能有一堆错误,这只是我的第一稿尝试。我必须自己测试一下,但我希望你能明白我的想法。只需查看流程,进行自己的修改,这应该可以正常工作。
我没有删除我的答案的第一部分,即使它不是这个问题的答案,只是为了如果您在该部分也遇到问题,选择尽可能高的数字,它可能会有所帮助你
祝你好运!
,我不是java程序员。但我认为这是一个逻辑问题。所以,我已经在python中为您解决了。我很确定您可以将其转换为java。
代码如下:
x = input('Enter the number:')
a = [2,6,7]
b = [6,9]
c = [4]
d = [4,7]
e = [8,10,15]
i = 0
z = 0
final_list = []
while i <= int(x):
try:
i += a[z]
final_list.append(a[z])
except BaseException:
pass
try:
i += b[z]
final_list.append(b[z])
except BaseException:
pass
try:
i += c[z]
final_list.append(c[z])
except BaseException:
pass
try:
i += d[z]
final_list.append(d[z])
except BaseException:
pass
try:
i += e[z]
final_list.append(e[z])
except BaseException:
pass
z += 1
print(final_list)