Hackerrank平均分配巧克力

时间:2019-11-21 20:37:02

标签: java algorithm

我正在查看此hackerrank问题声明-Equals

  

Christy正在HackerRank实习。有一天,她必须分发一些   巧克力给她的同事们。她偏爱她的朋友和   计划给他们比其他人更多的东西。项目经理之一   听到这个,告诉她确保每个人都一样   数字。

     

要使事情变得困难,她必须均衡巧克力的数量   在一系列操作中。对于每个操作,她可以给1、2或5   巧克力给一个同事以外的所有人。每个人都在吃巧克力   回合接收相同数量的棋子。

     

例如,假设起始分布为[1,1,5]。她可以给酒吧   到前两个,分布将为[3,3,5]。在下一轮,她   给出相同的两个2小节,每个人都有相同的数字:[5,5,5]。

     

给出一个初始分布,计算最小数量   需要进行的操作,以便每个同事拥有相同数量的   巧克力。

现在我发现这段代码在hackerrank中可以正常工作:

static int equal(int[] arr) {
    int min = Integer.MAX_VALUE;
    int n = arr.length;
    for (int i = 0; i < n; i++) {
        min = Math.min(min, arr[i]);
    }
    int bestResult = Integer.MAX_VALUE / 2;
    for (int borderline = min; borderline >= 0; borderline--) {
        int result = 0;
        for (int i = 0; i < n; i++) {
            result += (arr[i] - borderline) / 5;
            result += (arr[i] - borderline) % 5 / 2;
            result += (arr[i] - borderline) % 5 % 2 / 1;
        }
        bestResult = Math.min(bestResult, result);
    }
    return bestResult;
}

在上面的代码中,首先我们试图从数组中获取最小的元素,然后我无法理解如何使用嵌套循环来计算bestResult。我试图在日食中调试此代码,但无法理解该逻辑如何解决问题陈述。

能否请您帮助我理解此程序。

我还看到只有一个测试用例失败,这是什么原因。

2 个答案:

答案 0 :(得分:0)

如果我们理解这一算法,它将变得更加简单

  

给予除一个人以外的其他所有人==减少一个人并   不是所有人。

这意味着,我们知道最终值将是什么样。 n个数字的列表,所有数字均为min值。我们可以算出每个数字达到最少需要多少步。在示例[1,1,5]中,5花费了2步才能达到1,现在都相等。 这就是您在上方看到的内部循环(当borderlinemin时)。贪婪地将每个数字以最快的方式减少到最小。取尽可能多的5s,然后取2s,最后取1。

    for (int i = 0; i < n; i++) {
        result += (arr[i] - borderline) / 5;            // no. of 5s
        result += (arr[i] - borderline) % 5 / 2;        // from the remainder, no. of 2s
        result += (arr[i] - borderline) % 5 % 2 / 1;    // from the above remainder, no of 1s
    }

但是,这并不能解决所有情况。我们假设目标是在给定列表中达到“最小值”,但是有时达到最小值而不是最小值需要更少的步骤。所有值应收敛的该值是您粘贴的代码中的borderline变量。

让我们来[1,5,5]。如果我们应用与将所有元素都设为1相同的逻辑,那么我们将获得4个步骤。但是,将它们全部设为0,仅需3个步骤。

要确定是所有减少量都应计入min变量还是应少于min的其他数值,这是最好的基准, 外部循环正在检查0min之间的所有数字(这给出了最好的边界),该数字给出了最小的步长。

希望此说明阐明问题中的代码。

注意: 为了进行更多优化,该循环不需要从0min进行检查。如果基准线距离min较远,则只需要额外的步骤即可从min到达基准线,而不会给出最小的步骤,只会花费计算时间。

仅检查minmin-1min-2边界线就足够了。随着更多会导致额外的步骤。所以外环看起来像

 for (int borderline = min; borderline >= min-2; borderline--)

答案 1 :(得分:0)

result += (arr[i] - borderline) / 5; result += (arr[i] - borderline) % 5 / 2; result += (arr[i] - borderline) % 5 % 2 / 1;

这里:

  • (arr[i] - borderline) / 5给出可以减去5的次数
  • (arr[i] - borderline) % 5给出了剩下的内容
  • /2给出可以减去的2个数字
  • (arr[i] - borderline) % 5 % 2给出剩余的内容
  • /1给出可以减去1的次数

有关更多说明,您可以查看this link