通过迭代数组并将每个元素除以以1

时间:2019-01-17 06:10:20

标签: java algorithm

我有一个下面的方法,该方法迭代距离数组,并将每个元素除以以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;
  }

4 个答案:

答案 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)

我认为,我们可以做两件事来提高性能,但是该方法并不是最佳方法,它取决于列表的数量:

  • 减少迭代次数
  • 使用贪婪算法优先级降低最大值。为此,我们首先需要对列表进行排序,这可能会花费O(nlog(n))时间。

这样的代码

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;
    }
}