当前位置: 首页 > 知识库问答 >
问题:

如何知道我们应该添加的最少数字以获得完整的数组

洪璞瑜
2023-03-14

最近我遇到了这样一个问题:
假设有一个int N,还有一个int[],这个数组中的每个元素只能使用一次。我们需要设计一个算法,通过将这些数字相加得到1到N,最后返回需要相加的最少数字
例如:

N = 6, array is [1,3]
1 : we already have.
2 : we need to add it to the array.
3 : we can get it by doing 1 + 2.
4: 1 + 3.
5 : 2 + 3.
6 : 1 + 2 + 3.
So we just need to add 2 to our array and finally we return 1.

我正在考虑使用DFS解决这个问题。你有更好的解决方案吗?谢谢!

共有3个答案

贲俊才
2023-03-14

这是动态规划中的一个著名问题。你可以在这里参考完整的解决方案https://www.youtube.com/watch?v=s6FhG--P7z0

呼延英奕
2023-03-14

我不知道这是否是一个好的解决方案:

我会创建第二个数组(布尔数组),记住我能计算的所有数字。然后我将编写一个方法,模拟向数组中添加一个数字。(在您的示例中,1、3和2被添加到数组中)。将更新布尔数组,以始终记住哪些值(数字)可以使用添加的数字进行计算。

在对初始数组值调用add方法后,您测试每个Number x(1

由于我的解释是不行的,我将添加(未经测试)Java代码:

static int[] arr = {3,5};
static int N = 20;
//An Array remembering which values can be calculated so far
static boolean[] canCalculate = new boolean[N];

//Calculate how many numbers must be added to the array ( Runtime O(N^2) )
public static int method(){

    //Preperation (adding every given Number in the array)
    for(int i=0; i<arr.length; i++){
        addNumber(arr[i]);
    }

    //The number of elements added to the initial array
    int result = 0;

    //Adding (and counting) the missing numbers (Runtime O(N^2) )
    for(int i=1; i<=N; i++){
        if( !canCalculate[i-1] ){
            addNumber(i);
            result++;
        }
    }
    return result;
}


//This Method is called whenever a new number is added to your array
//runtime O(N)
public static void addNumber( int number ){
    System.out.println("Add Number: "+(number));

    boolean[] newarray = new boolean[N];
    newarray[number-1] = true;

    //Test which values can be calculated after adding this number
    //And update the array
    for(int i=1; i<=N; i++){
        if( canCalculate[i-1] ){
            newarray[i-1] = true;
            if( i + number <= N ){
                newarray[i+number-1] = true;
            }
        }
    }
    canCalculate = newarray;
}

编辑:测试了代码并更改了一些错误(但Rachel的解决方案似乎无论如何都更好)

仲孙翔飞
2023-03-14

以下是OP发布的解决方案为何有效的解释(简单地说,该算法是遍历已排序的现有元素,保留前面现有元素的累积和,并将一个元素添加到数组中,如果它不存在并且超过当前总和,则求和):

循环按必须形成的每个元素的顺序进行测试,并对前面的元素求和。如果需要的元素大于当前总和,它会提醒我们。如果你仔细想想,这真的很简单!当我们已经使用了前面的所有元素时,我们怎么能生成元素呢,这就是总和所表示的!

相反,当总和大于当前元素时,我们如何知道所有中间元素都能形成?例如,考虑n=7,a={}:

The function adds {1,2,4...} 
So we are up to 4 and we know 1,2,3,4 are covered,
each can be formed from equal or lower numbers in the array.

At any point, m, in the traversal, we know for sure that 
X0 + X1 ... + Xm make the largest number we can make, call it Y.
But we also know that we can make 1,2,3...Xm

Therefore, we can make Y-1, Y-2, Y-3...Y-Xm

(In this example: Xm = 4; Y = 1+2+4 = 7; Y-1 = 6; Y-2 = 5)

Q.E.D.
 类似资料:
  • 看过前面的文章,也许有许多朋友已经跃跃欲试想将自己主板上的BIOS升级了(有这种便宜,能不动心吗?)。别心急,我们先来看看升级BIOS的进行过程。首先,你必须知道自己的主板型号;其次,要确认主板上的BIOS的类型和版本;第三,到主板生产商的网页上去下载同自己主板型号和BIOS类型一致的BIOS升级程序;最后,进行BIOS升级操作。在这里,我们先介绍前两个步骤的实现方法。 如何查知电脑的主板类型?

  • 在过去的几天里做了一些阅读后,我已经取得了一些进展,下面是我想出的代码: 主要活动: HTTPRequest 没有错误,一切运行正常,但问题是-我已经建立了这个代码作为一个测试,如果我可以登录我试图登录的网站,但我无法从中获得任何信息。在我按下按钮后,似乎发生了什么事情,我发送到用户界面线程的输入流给了我这个:“java.io.BufferedInputStream@afe19b8”,每次按下按钮

  • 问题内容: 给定,例如1.25-如何获得该数字的“ 1”和“ .25”部分? 我需要检查小数部分是否为.0,.25,.5或.75。 问题答案: 然后与1 / 4、1 / 2、3 / 4等进行比较。 如果是负数,请使用以下方法: 在作出停止其 -1.25 到 -1 和 -0.25

  • 问题内容: 我有一个学校项目,可以解析网络代码并将其像数据库一样使用。当我尝试从(https://www.marathonbet.com/en/betting/Football/)提取数据时,我没有全部了解吗? 这是我的代码: 获得的结果(这是显示的联赛的最后一个): 在她上面显示所有联赛。 为什么我没有完整的数据?感谢您的时间! 问题答案: Jsoup的默认正文响应限制为1MB。您可以使用 ma

  • 我最近在Android Studio中又安装了一个Android SDK,即SDK版本4.4(API级别19),在与我的项目一起使用后,它在项目的文件夹()中添加了一组文件夹。 我既不明白为什么,也不明白如何使用它们。 我在SO上读到另一个关于它的问题。 答案是: 我还是不明白为什么要这样做。 为什么我们不能把应用程序图标也放在文件夹中呢? 此外,如果只应将应用程序图标放置在文件夹中,我如何创建其

  • 我计划使用这里记录的实时订阅系统,因为它解释了我们可以订阅一个位置ID,并在该位置接收关于新媒体的通知。我们推出了它,但立即开始失败,因为有一个未发布的30个订阅的限制(我想我们应该在开始构建它之前做更多的谷歌搜索)。 这基本上是在这里概述的相同的问题,但谈话真的很陈旧,我不确定最终目标是完全相同的,因为提出的解决方案对我没有帮助。 有太多的客户帐户注册更多的应用程序以获得足够的订阅(我们将不得不