我有一个下面的方法,该方法迭代距离数组,并将每个元素除以以1开头的数字,然后得到总和。如果sum大于传递给该方法的值points
,则再次在for循环中开始并除以2,继续进行直到找到小于值points
的和。
下面的代码可以工作,但是有什么办法可以更好地编写此代码?
public static int findMin(List<Integer> distance, int points) {
int sum = 0;
int c = 1;
while (true) {
for (Integer dist : distance) {
sum = (int) (sum + Math.ceil(dist / c));
}
if (sum <= points) {
break;
}
c++;
sum = 0;
}
return c;
}
答案 0 :(得分:1)
如果没有特定的理由对每个比率而不是最终的总和进行Math.ceil运算,则可以先获取所有元素的总和,然后找到c的值
总和/ c <=分
总和/点<= c
如果0 <(总和/点)<1,c = 1
else c = Math.ceil(总和/点)
答案 1 :(得分:0)
2019-01-08
答案 2 :(得分:0)
如果我错了,请纠正我,但假设距离集为[1, 2, 3]
对吗?然后,您从1/1 + 2/1 + 3/1
开始(该变量在这里保留为小数)等于6/1
,因为它们在这里都具有相同的“分母”,所以它不会改变。因此,这意味着第一次迭代除以一个,实际上是值的总和。 (1 + 2 + 3) / 1
除以1。任何除以1的东西都是它本身。所以这就是总和。
现在。在第二遍中,如果我正确假设的话,1/2 + 2/2 + 3/2
–再次将它们保留为分数– (1 + 2 + 3) / 2
= 6/2
。现在,您应该看到一种模式,对吗?第一遍是6/1
,第二遍是6/2
,下一遍是6/3
...
那又如何:
public static int findMin(List<Integer> distance, int points) {
int sum = 0;
for (Integer i : distance) {
sum += i;
}
int min = 1;
while (sum / min > points) {
min += 1;
}
return min;
}
也许这样的解决方案行得通吗?
编辑因此,事实证明,该解决方案(至少部分地)假设了一定的数学准确性,但是似乎每个元素的除法要求是整数除法,这会使某些结果产生偏差如果我们严格按照数学方法进行处理。因此,虽然不是直接解决问题的方法,但我觉得足够正确,可以将其作为解决方案。
答案 3 :(得分:0)
我认为,我们可以做两件事来提高性能,但是该方法并不是最佳方法,它取决于列表的数量:
这样的代码
public static int findMin(List<Integer> distance, int points) {
int sum = 0;
int c = 1;
// sort the list for implement greedy algorithm
Collections.sort(distance, Comparator.reverseOrder());
while (true) {
for (Integer dist : distance) {
sum += dist / c;
// reduce the times of iterate
if (sum <= points) {
return c;
}
}
c++;
sum = 0;
}
}