Problem
Given an integer array, heapify it into a min-heap array.
For a heap array A
, A[0]
is the root of heap, and for each A[i]
, A[i * 2 + 1]
is the left child of A[i]
and A[i * 2 + 2]
is the right child of A[i]
.
Clarification
What is heap?
Heap is a data structure, which usually have three methods: push, pop and top. where "push" add a new element the heap, "pop" delete the minimum/maximum element in the heap, "top" return the minimum/maximum element.
What is heapify?
Convert an unordered integer array into a heap array. If it is min-heap, for each element A[i]
, we will get A[i * 2 + 1]
>= A[i]
and A[i * 2 + 2]
>= A[i]
.
What if there is a lot of solutions?
Return any of them.
Example
Given [3,2,1,4,5]
, return [1,2,3,4,5]
or any legal heap array.
Challenge
O(n) time complexity
Note
首先,先搞懂几个概念:heap,min-heap,complete tree。这里只要知道heap是一种complete tree的树结构,结点i的左右子结点的index为2*i+1
和2*i+2
,min-heap是子结点大于根节点的树,就大概明白题目要怎么heapify了。
思路是从底部开始构建数组,将较小的结点移向上层结点。先取数组末尾的两个元素为left
和right
,若2*i+1
和2*i+2
越界,则赋Integer.MAX_VALUE
,这样可以在后面的分支语句避免对越界情况不必要的讨论。然后,取left
和right
的较小者和上层A[i]
结点交换,实现min-heap结构。交换了A[i]
和A[2*i+1]/A[2*i+2]
之后,还要重新heapify被交换到末位的原先的A[i]
,即交换之后的A[2*i+1]/A[2*i+2]
。然后i
不断减小,直到整个数组完成heapify。
其实,这就相当于对数组A进行堆排序。
Arrays.sort(A);
Solution
public class Solution {
public void heapify(int[] A) {
for (int i = A.length/2; i >= 0; i--) {
helper(A, i);
}
}
public void helper(int[] A, int i) {
if (i > A.length) return;
int left = 2*i+1 < A.length ? A[2*i+1] : Integer.MAX_VALUE;
int right = 2*i+2 < A.length ? A[2*i+2] : Integer.MAX_VALUE;
if (left < right && left < A[i]) {
A[2*i+1] = A[i];
A[i] = left;
helper(A, 2*i+1);
}
else if (right < A[i]) {
A[2*i+2] = A[i];
A[i] = right;
helper(A, 2*i+2);
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。