【问题标题】:How to find number of possible ways to pick numbers greater than or equal to a given number from multiple lists?如何找到从多个列表中选择大于或等于给定数字的数字的可能方法的数量?
【发布时间】:2020-12-20 07:11:30
【问题描述】:

我正在尝试从多个数组列表中选择一个数字,并找到所有可能的方法来选择这些数字,以使这些数字的总和大于给定的数字。我只能想到蛮力实现。

例如,我有五个数组列表,例如

A = [2, 6, 7]

B = [6, 9]

C = [4]

D = [4, 7]

E = [8, 10, 15]

给定的数字是 40。 然后从每个列表中选择一个数字后,所有可能的方法都可以是

[7, 9, 4, 7, 15]
[6, 9, 4, 7, 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。

【问题讨论】:

  • 你在哪里解决这个问题?
  • 我已经添加了我尝试的实现。你能重新打开我的问题吗?
  • 提示:使用递归。
  • 即使我使用递归,步数不会保持不变吗?我不能跳过一个数字,即使它远小于阈值 k,因为在另一个列表中可能有一个更大的数字可以使总和超过阈值。
  • 这个问题还能再开吗?

标签: algorithm combinatorics


【解决方案1】:

我不是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)

【讨论】:

  • 您好 Sonet Adhikary,感谢您的回复。不用转成Java,我能看懂python。我相信你没有正确理解这个问题。我们不必从列表中找到所有数字,使得它们的总和大于或等于 x,而是我们必须找到所有可能的方法从每个列表中一次选择一个数字,使得它们的总和大于x 并打印所有可能的方式。
【解决方案2】:

一种方法是这样。必须至少有一个解决方案,您可以从每个数组中选择一个数字并将它们相加以大于或等于另一个。

考虑到数组可能有任意顺序的随机数,首先使用此排序函数将它们按降序排列(最大的数字在前,最小的数字在后):

 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)

这仅供参考,代码可能不起作用,它可能有很多错误,这只是我的第一次草稿尝试。我必须自己测试它,但我希望你能看到我来自哪里。只需查看流程,进行自己的修改,这应该可以正常工作。

我没有删除我的答案的第一部分,即使它不是这个问题的答案,所以如果你在该部分也遇到问题,选择尽可能高的数字,它可能会有所帮助你

祝你好运!

【讨论】:

  • 嗨 FieryFalcon,感谢您的回复。编辑后您的想法是正确的,但我相信实施将无法正常工作,因为我们采用随机元素,这意味着它们可以重复,这将导致步骤数量增加。此外,这意味着我们可能不会遍历所有可能的选择号码。再次感谢您尝试帮助我解决问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 2023-04-02
  • 2016-04-17
  • 1970-01-01
  • 2012-11-20
相关资源
最近更新 更多