【问题标题】:The code I wrote for this hackerrank test works but is too resource and now I am out of ideas. What am I doing wrong?我为这个hackerrank测试编写的代码可以工作,但是资源太多,现在我没有想法了。我究竟做错了什么?
【发布时间】:2020-09-02 19:33:48
【问题描述】:

New Year Chaos Problem: Hackerrank

这是我编写的程序,它告诉我我的代码没有及时完成(我需要对其进行优化以使其在更短的时间内完成)。我已经尽我所能,但我没有想法,我该怎么办?

fun minimumBribes(q: Array<Int>) {
    var bribeCount = 0
    for ((i, x) in q.withIndex()) {

        val last = q.lastIndex - i + 1
        val first = i + 1


        // Checks if any of the elements have more than 2 elements smaller than them behind them in the queue and returns out of the function if so (because no element can bribe more than 2 elements)
        // Drops all the elements in the queue before x and counts the number of smaller elements after x in the queue
        if (q.drop(first).count { it < x } > 2) {
            println("Too chaotic")
            return
        }

        // Adds the number of elements bigger than x that are in the queue standing ahead of x to bribeCount (since the number of bribes taken by all elements will be equal to the total number of bribes given in total and no element can get past ahead of a smaller element without bribing it)
        bribeCount += q.dropLast(last).count { it > x }

    }
    println(bribeCount)
}

阅读页面顶部链接的第一个问题。在阅读问题陈述之前,您可能不会理解此行以下的任何内容。

如您所见,为了检查贿赂元素的人数,我计算了从该元素中具有更大价值并且在队列中站在它之前的元素的数量。通过将每个元素收到的贿赂数量相加,我们可以计算出总共提供的贿赂数量。但在此之前,我计算了小于队列中位于其后的元素的元素数量,如果该数字大于 2,则表示该元素贿赂了超过 2 个人,这是“太混乱”,我返回。

这是我收到的错误消息:Screenshot

【问题讨论】:

  • 为什么JavaKotlin都参与了这段代码?
  • 我肯定在这里看不到任何 Java。我什至不懂Java。

标签: arrays performance loops kotlin


【解决方案1】:

您的代码的问题在于它使用了太多循环。

  1. Array.drop(Int)Array.dropLast(Int) 都使用循环构造 List,然后返回。
  2. Iterable&lt;T&gt;.count((T) -&gt; Boolean) 使用循环来计算指定条件为真的次数。

要优化您的代码,请删除这些使用循环的扩展函数。

fun minimumBribes(queue: Array<Int>): Unit {
    var bribeCount = 0

    for ((index, initialPosition) in queue.withIndex()) {
        val currentPosition = index + 1

        if ((initialPosition - currentPosition) > 2) {
            println("Too chaotic")
            return
        }

        val startingCheckIndex = max(0, initialPosition - 2)

        for (checkIndex in startingCheckIndex until index) {
            val hasBribed = queue[checkIndex] > initialPosition
            if (hasBribed) bribeCount++
        }
    }

    println(bribeCount)
}

澄清:

对于队列中的每个号码:

1:我们检查一个人在队列中上升了多远,即initialPosition - currentPosition。如果他/她已经上升了 2 个以上的位置,那么我们会打印“太混乱”并返回控制权,因为此人不可能在他/她之前贿赂超过 2 个人。

例如,如果这个人的贴纸上写着 6,而他当前的位置是 3,那么这个人已经上升了 3 个位置,这是不可能的。

2:你在问题​​中提到,I count the number of elements that have a bigger value from that element and are standing before it in the queue

这是正确的,因为我们正在计算一个人收受了多少贿赂,但我们无法直接检查到第一个位置。作为一个贿赂他人的人只能在他之前移动一个位置,我们只会在该人的初始位置之前检查最多1个位置。我在我的代码中调用了这个位置的索引startingCheckIndex

例如:如果这个人的贴纸上写着 5,而当前位置是 10。那么我们只会从位置 4 到 10 进行检查。

注意我使用了max(0, initialPosition - 2)
-2因为数组索引从0开始,initialPosition从1开始。
max(0,..)因为对于initialPosition 1,1 - 2 = -1所以我们需要维护最小值为 0。

【讨论】:

  • ``` val startingCheckPosition = max(0, initialPosition - 2) for (position in startingCheckPosition until currentPosition) { //统计初始位置较大的人数,即受贿人数 val hasBribed = queue [position] > initialPosition if (hasBribed) bribeCount++ }``` 你能详细解释一下这部分吗?你为什么在那里做一个最大值,你所说的startingCheckPosition是什么意思?如果currentPosition 小于startingCheckPosition 怎么办?然后循环不会执行。
  • @SbeveSbren 我已经更新了我的答案,包括对我的代码的说明。
  • 我还是听不懂它在说什么,但我会更加努力。代码 defo 有效,所以我没有任何疑问,我会自己尝试弄清楚。谢谢。如果我需要帮助,我会在这里提到你
  • 非常感谢您的帮助,直到现在我才感谢您,因为我没有时间阅读您的代码,我今天做了并且很清楚。它确实需要我一个小时才能准确理解你在做什么以及为什么它会起作用哈哈,但它很棒而且非常聪明。感谢您的帮助。
猜你喜欢
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
  • 2020-01-13
  • 2022-06-10
相关资源
最近更新 更多