微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的算法不适用于 codility 的曼哈顿天际线

如何解决为什么我的算法不适用于 codility 的曼哈顿天际线

我正在执行来自 codility 的训练任务。我以 100/100 的速度完成了 StoneWall,但我仍然坚持该任务中曼哈顿天际线问题的主要思想。此处描述了该任务https://app.codility.com/programmers/task/stone_wall/

当我第一次读到这个问题时,我意识到我应该只计算建造墙的最小石块数量。关于如何扩展块等没有任何解释。(可能假设包括我必须提前知道它。但我从未处理过这样的问题)。基于我对这个问题的理解,我实现了下一个算法(结果证明是错误的)

public int solution(final int[] H)
    {
        if (H.length == 1)
        {
            return 1;
        }

        int blocks = 0;
        int first = 0;
        for (int i = 1; i <= H.length; i++)
        {
            if (i == H.length || H[first] > H[i])
            {
                for (int k = first; k < i; k++)
                {
                    if (H[k] != 0)
                    {
                        for (int t = k + 1; t < i && H[k] <= H[t]; t++)
                        {
                            if (H[t] >= H[k])
                            {
                                H[t] = H[t] - H[k];
                            }
                            else
                            {
                                break;
                            }
                        }
                        blocks++;
                    }
                }
                first = i;
            }
        }
        return blocks;
    }

以上代码适用于简单的小数组。例如 { 8,8,5,7,9,4,8 }。显然它失败了。我想运行它以了解我的正确方式。但它返回不正确的结果,例如值在 1...20 范围内的大数组。问题是我不明白建墙过程的主要思想,所以我无法在我的本地复制它。

然后我研究了一下,发现了这个关于 codility https://codility.com/media/train/solution-stone-wall.pdf解决方

The intuition is that by extending each stone block to the ground,we obtain a set of
buildings forming the given skyline.

我认为这是一个线索。(我应该把较小的积木堆在较大的积木之上。)但后来我看了看那些可能排列积木的数字,这又让我感到困惑。

  1. https://app.codility.com/programmers/task/stone_wall/

    2.

    https://codility.com/media/train/solution-stone-wall.pdf

最后我使用上面的第二张图片实现了它并且效果很好(100% 编码)

public int solution2(final int[] H)
    {
        if (H.length == 1)
        {
            return 1;
        }

        int blocks = 0;
        final arraydeque<Integer> stack = new arraydeque<Integer>();
        stack.push(H[0]);

        for (int i = 1; i < H.length; i++)
        {

            while (stack.size() > 0 && stack.peek() > H[i])
            {
                stack.pop();
                blocks++;
            }
            if (stack.isEmpty() || stack.peek() < H[i])
            {
                stack.push(H[i]);
            }
        }

        return blocks + stack.size();
    }

有人能解释一下为什么第一个算法不适用于这个任务吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。