Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
整数分区的JavaScript递归实现_Javascript_Algorithm_Recursion - Fatal编程技术网

整数分区的JavaScript递归实现

整数分区的JavaScript递归实现,javascript,algorithm,recursion,Javascript,Algorithm,Recursion,问题:不重新排列的整数分区 输入:非负数{s1,…,sn}和整数k的排列输出:将S划分为k个或更少范围的最大作业,以最小化所有范围的最大和,而不重新排序任何数字 示例输入=[100200300400500600700800900]应输出最大的作业,该作业仅为1700,因为数组最好是分区为100200300400500 | 600700 | 800900 我的功能不起作用。例如,当它应该输出1700时,它输出2400。不知道怎么了 我的代码 var integerPartitionRec=函数(n

问题:不重新排列的整数分区
输入:非负数{s1,…,sn}和整数k的排列
输出:将S划分为k个或更少范围的最大作业,以最小化所有范围的最大和,而不重新排序任何数字

示例输入=
[100200300400500600700800900]
应输出最大的作业,该作业仅为1700,因为数组最好是分区为
100200300400500 | 600700 | 800900

我的功能不起作用。例如,当它应该输出1700时,它输出2400。不知道怎么了

我的代码
var integerPartitionRec=函数(n,k,S){
函数和(p,c){
返回p+c;
}
如果(i==1)返回S[1];
如果(k==1)返回S.slice(0,n),则减少(sum);
var成本,最小成本=Number.MAX\u值;
对于(变量i=1;i
我做了一些随机更改,现在打印1700

var integerPartitionRec = function(n, k, S) {
    function sum(p, c) {
        return p + c;
    }

    if (n === 1) return S[1];
    if (k === 1) return S.slice(0, n).reduce(sum);

    var cost, min_cost = Number.MAX_VALUE;
    for (var i = 1; i < n; i++) {
        cost = Math.max(integerPartitionRec(i, k - 1, S), S.slice(i, n).reduce(sum));
        min_cost = Math.min(min_cost, cost);
    }

    return min_cost;
};

var run = function() {

    var test = [100, 200, 300, 400, 500, 600, 700, 800, 900];

    console.log(integerPartitionRec(test.length, 3, test));
};

run();
var integerPartitionRec=函数(n,k,S){
函数和(p,c){
返回p+c;
}
如果(n==1)返回S[1];
如果(k==1)返回S.slice(0,n),则减少(sum);
var成本,最小成本=Number.MAX\u值;
对于(变量i=1;i

但我更愿意使用另一种算法:您可以对答案使用二进制搜索,然后检查
O(n)
是否可以将数组划分为
k
部分,其中每个部分都小于某个常数。如果我理解您的算法,它将是
O(n log sum)
而不是
O(n^2)

  • 如果
    n==1
    您有一个大小为1的数组,无法拆分,因此最佳解决方案是不拆分并返回元素的值,该值也是整个数组的总和:
    S[0]
    (您错误地放置了
    S[1]
  • 如果
    k==1
    无法再拆分,则返回整个数组的总和
  • 否则,尝试在任何可能的位置拆分(除了最开始的
    i=0
    和最末尾的
    i=n
    ,因为这些都是假拆分,如果可以拆分,最好这样做),检查结果如何,并采用最佳拆分

但是在递归调用中,您应该只考虑到“代码< N>代码>的数组,而在代码中,在这行中:

cost = Math.max(integerPartitionRec(i, k - 1, S), S.slice(i).reduce(sum));

您考虑整个数组,因为<代码> S切片(i)。将(和)求和从i到数组的末尾,即使从<代码> N< /代码>到结束,已经在前一个调用的“尾部”中计算,所以您考虑它两次! 您可以通过告诉slice在

n
处停止来解决此问题:

cost = Math.max(integerPartitionRec(i, k - 1, S), S.slice(i, n).reduce(sum));
或者,您可以通过仅将拆分的第一部分传递给递归调用来避免使用
n

var integerPartitionRec = function(k, S) {
    function sum(p, c) {
        return p + c;
    }

    if (k === 1 || S.length === 1) return S.reduce(sum);

    var cost, min_cost = Number.MAX_VALUE;
    for (var i = 1; i < S.length; i++) {
        cost = Math.max(integerPartitionRec(k - 1, S.slice(0, i)), S.slice(i).reduce(sum));
        min_cost = Math.min(min_cost, cost);
    }

    return min_cost;
};
var integerPartitionRec=函数(k,S){
函数和(p,c){
返回p+c;
}
如果(k==1 | | S.length==1)返回S.reduce(sum);
var成本,最小成本=Number.MAX\u值;
对于(变量i=1;i
这里有问题吗?还是你只是在分享你的代码?代码不起作用。对于示例输入,它应该返回1700,但返回2400如果(i==1)返回S[1];,则返回的是
i
@RiaD我认为应该是
n
你做了一些随机更改?我最终将其更改为
cost=Math.max(integerPartitionRec(I,k-1,S,S.slice(I,n).reduce(sum))
但是你的回答告诉了我什么是错的。谢谢,这也是一个有效的解决方案,编辑了我的回答,解释了什么是错的,并显示了可能的解决方案,现在让我知道是否更清楚。
var integerPartitionRec = function(k, S) {
    function sum(p, c) {
        return p + c;
    }

    if (k === 1 || S.length === 1) return S.reduce(sum);

    var cost, min_cost = Number.MAX_VALUE;
    for (var i = 1; i < S.length; i++) {
        cost = Math.max(integerPartitionRec(k - 1, S.slice(0, i)), S.slice(i).reduce(sum));
        min_cost = Math.min(min_cost, cost);
    }

    return min_cost;
};