Javascript 如何解决可变性最小最大除法
我一直在努力解决1H30的编码问题,以及如何用二进制搜索解决这个问题。我找到了答案,但我不明白背后的逻辑。有人能告诉我这个答案吗 这就是问题所在 任务描述 给定整数K、M和非空的零索引数组a 由N个整数组成。数组中的每个元素都不是更大的 比M 您应该将此数组划分为K个连续元素块。 块的大小是介于0和N之间的任意整数 数组应该属于某个块 从X到Y的块总和等于A[X]+A[X+1]+…+A[Y]。 空块的和等于0 大和是任何块的最大和 例如,给定整数K=3、M=5和这样的数组 即: A[0]=2A[1]=1A[2]=5A[3]=1A[4]=2A[5]=2Javascript 如何解决可变性最小最大除法,javascript,algorithm,binary-search-tree,Javascript,Algorithm,Binary Search Tree,我一直在努力解决1H30的编码问题,以及如何用二进制搜索解决这个问题。我找到了答案,但我不明白背后的逻辑。有人能告诉我这个答案吗 这就是问题所在 任务描述 给定整数K、M和非空的零索引数组a 由N个整数组成。数组中的每个元素都不是更大的 比M 您应该将此数组划分为K个连续元素块。 块的大小是介于0和N之间的任意整数 数组应该属于某个块 从X到Y的块总和等于A[X]+A[X+1]+…+A[Y]。 空块的和等于0 大和是任何块的最大和 例如,给定整数K=3、M=5和这样的数组 即: A[0]=2A[
A[6]=2 例如,可以将阵列划分为以下块: [2,1,5,1,2,2,2],[],金额较大的15;[2], [1, 5, 1, 2] ,[2,2]中的一个较大的值为9;[2,1,5],[1,2,2,2]和 大额8元;[2,1]、[5,1]、[2,2,2]以及一个6的大总和 目标是最大限度地减少巨额金额。在上面的示例中,6是 最小的大数目 编写一个函数: 函数解(K,M,A) 给定整数K,M和非空的零索引数组a 由N个整数组成,返回最小的大和 例如,给定K=3,M=5和数组A,使得: A[0]=2A[1]=1A[2]=5A[3]=1A[4]=2A[5]=2
A[6]=2 函数应该返回6,如上所述 假设: N和K是[1..100000]范围内的整数; M是[0..10000]范围内的整数; 数组A的每个元素都是[0..M]范围内的整数 这是我能得到的答案
function solution(K, M, A) {
var begin = A.reduce((a, v) => (a + v), 0)
begin = parseInt((begin+K-1)/K, 10);
var maxA = Math.max(A);
if (maxA > begin) begin = maxA;
var end = begin + M + 1;
var res = 0;
while(begin <= end) {
var mid = (begin + end) / 2;
var sum = 0;
var block = 1;
for (var ind in A) {
var a = A[ind];
sum += a;
if (sum > mid) {
++block;
if (block > K) break;
sum = a;
}
}
if (block > K) {
begin = mid + 1;
} else {
res = mid;
end = mid - 1;
}
}
return res;
}
函数解(K,M,A){
var begin=A.reduce((A,v)=>(A+v),0)
begin=parseInt((begin+K-1)/K,10);
var maxA=数学最大值(A);
如果(maxA>begin)begin=maxA;
var end=begin+M+1;
var-res=0;
while(中期开始){
++块;
如果(块>K)中断;
总和=a;
}
}
如果(块>K){
开始=中间+1;
}否则{
res=中等;
结束=中间-1;
}
}
返回res;
}
这是解决方案中的一个关键问题。对于每个候选解,我们在整个数组上迭代一次,在超过候选解之前,将数组块填充到块可以达到的最大和。如果求和不可行,那么尝试较小的求和是没有意义的,因此我们搜索更高可能的候选空间。如果求和是可以实现的,我们可以尝试较低的候选空间。这是一个关于解决方案的问题。对于每个候选解,我们在整个数组上迭代一次,在超过候选解之前,将数组块填充到块可以达到的最大和。如果求和不可行,那么尝试较小的求和是没有意义的,因此我们搜索更高可能的候选空间。如果求和是可以实现的,我们可以尝试较低的候选空间。我对代码做了一点修改,使其更清晰,但下面是我的解释:
/*
K=块数
M=最大数量
A=数组
*/
函数解决方案(numberOfBlocks、maxNumber、array){
让begin=array.reduce((a,b)=>(a+b),0);//计算a的总和
begin=Math.ceil(begin/numberOfBlocks);//计算每个块的平均值
begin=Math.max(begin,Math.max(…数组));//如果>大于平均值,则将begin设置为数组中的最大值
//简而言之:begin现在是可能的最小块和
//计算最大可能的块和
让end=begin+maxNumber+1;
var结果=0;
而(开始)中点意味着我们是
//在另一个街区。。。
如果(currentBlockSum>中点){
++块;
//…所以我们用当前的数字重置总和
currentBlockSum=数字;
//但是如果我们没有区块,我们的猜测(中点)是错误的
//我们必须调整它
如果(块>块数)
打破
}
}
//如果我们没有街区了
//这意味着我们的猜测(中点)比我们想象的要大
如果(块>块数){
开始=中点+1;
//否则,它会更小
}否则{
结果=中点;
结束=中点-1;
}
}
返回结果;
}
我对代码做了一点修改,使其更加清晰,但以下是我的解释:
/*
K=块数
M=最大数量
A=数组
*/
函数解决方案(numberOfBlocks、maxNumber、array){
让begin=array.reduce((a,b)=>(a+b),0);//计算a的总和
begin=Math.ceil(begin/numberOfBlocks);//计算每个块的平均值
begin=Math.max(begin,Math.max(…数组));//如果>大于平均值,则将begin设置为数组中的最大值
//简而言之:begin现在是可能的最小块和
//计算最大可能的块和
让end=begin+maxNumber+1;
var结果=0;
而(开始)中点意味着我们是
//在另一个街区。。。
如果(currentBlockSum>中点){
++块;
//…所以我们用当前的数字重置总和
currentBlockSum=数字;
//但是如果我们没有区块,我们的猜测(中点)是错误的
//我们必须调整它
如果(块>块数)
打破
}
}
//如果我们