【问题标题】:Count swaps in Binary Heap计算二进制堆中的交换
【发布时间】:2020-09-09 12:12:18
【问题描述】:

从 1 到 n 的数字按一定顺序添加到最小堆中。对于每个数字,找出它在最小堆中改变位置的次数。

澄清:对于添加使用方法Insert(),添加节点的顺序与它们在输入中的顺序相同。

输入:第一行是数字n。在第二行,除以空格,是从 1 到 n 的 n 个数字。

输出:n个数除以空格:第i个数表示第i个数在构建的最小堆中的位置变化次数。

即5 4 3 2 1

回答 2 3 3 2 2

public class MinHeap {
private int[] heap;
private int size;
private int maxsize;

public MinHeap(int maxsize) {
    this.maxsize = maxsize;
    this.size = 0;
    heap = new int[this.maxsize + 1];
    heap[0] = Integer.MIN_VALUE;
}

private void swap(int fpos, int spos) {
    int tmp;
    tmp = heap[fpos];
    heap[fpos] = heap[spos];
    heap[spos] = tmp;
}

private void minHeapify(int pos) {
    if (2 * pos == size) {
        if (heap[pos] > heap[2 * pos]) {
            swap(pos, 2 * pos);
            minHeapify(2 * pos);
        }
        return;
    }

    if (2 * pos <= size) {
        if (heap[pos] > heap[2 * pos] || heap[pos] > heap[2 * pos + 1]) {
            if (heap[2 * pos] < heap[2 * pos + 1]) {
                swap(pos, 2 * pos);
                minHeapify(2 * pos);
            }
            else {
                swap(pos, 2 * pos + 1);
                minHeapify(2 * pos + 1);
            }
        }
    }
}

public void insert(int element) {
    heap[++size] = element;
    int current = size;

    while (heap[current] < heap[current / 2]) {
        swap(current, current / 2);
        current = current / 2;
    }
}

public void minHeap() {
    for (int pos = (size / 2); pos >= 1; pos--) {
        minHeapify(pos);
    }
}

public int extractMin() {
    if (size == 0) {
        throw new NoSuchElementException("Heap is empty");
    }
    int popped = heap[1];
    heap[1] = heap[size--];
    minHeapify(1);
    return popped;
}

}

我不会数数

【问题讨论】:

  • 您的堆实现将根放在数组中的索引 1 处。数组从 0 开始,如果您使用 Java 等基于 0 的语言构建堆,则堆应该从 0 开始。请参阅stackoverflow.com/a/49806133/56778

标签: java binary heap


【解决方案1】:

评论后更新

我不知道你是如何得到输出“0 1 2 2 3”的。我本来期望“0 1 1 2 2”。但这已经无关紧要了。

我明白我误解了你原来的问题。您不希望插入每个项目时的交换次数。您想知道每个项目在堆的整个生命周期中改变位置的次数。

您需要构建一个映射,其中键是项目的值,值部分是项目参与交换操作的次数。在您的swap 方法中,您检查地图以查看该项目是否存在。如果地图中不存在该项目,则将其添加到计数 1。如果确实存在,则增加其计数。

在堆中添加完项目后,您可以打印地图的内容。

原答案

你可以有一个名为numSwaps的类变量:

private int numSwaps;

然后在你的swap 方法中,只要有交换,你就增加它:

private void swap(int fpos, int spos) {
    int tmp;
    tmp = heap[fpos];
    heap[fpos] = heap[spos];
    heap[spos] = tmp;
    numSwaps = numSwaps + 1;
}

并提供方法clearSwaps(重置为0)和getSwaps(返回当前交换次数)。

【讨论】:

  • 不,它没有帮助。我修改了 MinHeap 类:重新创建从零开始的堆(从scanner.nextInt 添加第一个值),然后继续从scanner 读取其他元素。当我添加 5 4 3 2 1 时,控制台回答 0 1 2 2 3,但答案应该是 2 3 3 2 2
  • 该死,前几天试了Map,不明白为什么正确的答案没有出来就扔了,以为我挖错方向了,结果发现地图真的会有所帮助。谢谢
猜你喜欢
  • 2021-03-05
  • 1970-01-01
  • 2013-07-08
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 2019-09-22
  • 2017-06-05
相关资源
最近更新 更多