|
| 1 | +/* |
| 2 | + Implement a Min-Heap class that supports |
| 3 | +
|
| 4 | + Building a Min Heap from an input array of integers. |
| 5 | + Inserting integers in the heap. |
| 6 | + Removing the heap's minimum / root value. |
| 7 | + Peeking at the heap's minimum / root value. |
| 8 | + Sifting integers up and down the heap, which is to be used when inserting and removing values. |
| 9 | +
|
| 10 | + Note that the heap should be represented in the form of an array. |
| 11 | +
|
| 12 | + Explanation: |
| 13 | +
|
| 14 | + The code snippet implements a MinHeap data structure in Go. |
| 15 | +
|
| 16 | + - `NewMinHeap`: This function creates a new MinHeap from an input array and returns a pointer to the MinHeap object. |
| 17 | + It calls the `BuildHeap` method to construct the heap structure. |
| 18 | + - `BuildHeap`: This method constructs the heap by iteratively calling `siftDown` on each parent node starting from the |
| 19 | + last non-leaf node. |
| 20 | + - `siftDown`: This method corrects the heap property by moving an element down the heap until it reaches its correct position. It compares the element with its children and swaps it with the smaller child if necessary. |
| 21 | + - `siftUp`: This method corrects the heap property by moving an element up the heap until it reaches its correct position. |
| 22 | + It compares the element with its parent and swaps it if necessary. |
| 23 | + - `Peek`: This method returns the minimum element in the heap (the root of the heap) without removing it. |
| 24 | + - `Remove`: This method removes and returns the minimum element in the heap. It swaps the root with the last element, |
| 25 | + removes the last element from the heap, and then calls `siftDown` to maintain the heap property. |
| 26 | + - `Insert`: This method inserts a new element into the heap. It appends the element to the end of the heap and then |
| 27 | + calls `siftUp` to maintain the heap property. |
| 28 | + - `swap`: This method swaps two elements in the heap given their indices. |
| 29 | + - `length`: This method returns the number of elements in the heap. |
| 30 | +
|
| 31 | + Overall, this code provides a basic implementation of a MinHeap data structure, allowing for efficient insertion, removal, |
| 32 | + and retrieval of the minimum element. |
| 33 | +
|
| 34 | + BuildHeap: O(n) time | O(1) space - where n is the length of the input array |
| 35 | + SiftDown: O(log(n)) time | O(1) space - where n is the length of the heap |
| 36 | + SiftUp: O(log(n)) time | O(1) space - where n is the length of the heap |
| 37 | + Peek: O(1) time | O(1) space |
| 38 | + Remove: O(log(n)) time | O(1) space - where n is the length of the heap |
| 39 | + Insert: O(log(n)) time | O(1) space - where n is the length of the heap |
| 40 | +
|
| 41 | +*/ |
| 42 | +import java.util.Arrays; |
| 43 | + |
| 44 | +public class MinHeap { |
| 45 | + private int[] heap; // The heap represented as an array |
| 46 | + private int size; // The current size of the heap |
| 47 | + |
| 48 | + public MinHeap(int[] array) { |
| 49 | + heap = Arrays.copyOf(array, array.length); // Create a copy of the input array |
| 50 | + size = array.length; |
| 51 | + buildHeap(); // Build the heap |
| 52 | + } |
| 53 | + |
| 54 | + private void buildHeap() { |
| 55 | + int first = (size - 2) / 2; // Start from the last parent node |
| 56 | + for (int currentIdx = first; currentIdx >= 0; currentIdx--) { |
| 57 | + siftDown(currentIdx); |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + private void siftDown(int currentIndex) { |
| 62 | + int childOneIdx = currentIndex * 2 + 1; // Calculate the index of the first child |
| 63 | + while (childOneIdx < size) { |
| 64 | + int childTwoIdx = -1; // Initialize the index of the second child |
| 65 | + if (currentIndex * 2 + 2 < size) { |
| 66 | + childTwoIdx = currentIndex * 2 + 2; // Calculate the index of the second child if it exists |
| 67 | + } |
| 68 | + int indexToSwap = childOneIdx; // Assume the first child is the one to swap with |
| 69 | + if (childTwoIdx > -1 && heap[childOneIdx] > heap[childTwoIdx]) { |
| 70 | + // If the second child exists and is smaller, update the index to swap with |
| 71 | + indexToSwap = childTwoIdx; |
| 72 | + } |
| 73 | + if (heap[currentIndex] > heap[indexToSwap]) { |
| 74 | + // If the current element is greater than the one to swap with, perform the swap |
| 75 | + swap(currentIndex, indexToSwap); |
| 76 | + currentIndex = indexToSwap; |
| 77 | + childOneIdx = currentIndex * 2 + 1; // Update the index of the first child |
| 78 | + } else { |
| 79 | + return; |
| 80 | + } |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + private void siftUp() { |
| 85 | + int currentIdx = size - 1; // Start from the last element |
| 86 | + int parentIdx = (currentIdx - 1) / 2; // Calculate the index of the parent |
| 87 | + while (currentIdx > 0) { |
| 88 | + int current = heap[currentIdx]; |
| 89 | + int parent = heap[parentIdx]; |
| 90 | + if (current < parent) { |
| 91 | + // If the current element is smaller than the parent, perform the swap |
| 92 | + swap(currentIdx, parentIdx); |
| 93 | + currentIdx = parentIdx; |
| 94 | + parentIdx = (currentIdx - 1) / 2; // Update the index of the parent |
| 95 | + } else { |
| 96 | + return; |
| 97 | + } |
| 98 | + } |
| 99 | + } |
| 100 | + |
| 101 | + public int peek() { |
| 102 | + if (size == 0) { |
| 103 | + return -1; |
| 104 | + } |
| 105 | + return heap[0]; // Return the minimum element at the top of the heap |
| 106 | + } |
| 107 | + |
| 108 | + public int remove() { |
| 109 | + swap(0, size - 1); // Swap the root with the last element |
| 110 | + int peeked = heap[size - 1]; // Remove the last element (minimum) and store it |
| 111 | + size--; |
| 112 | + siftDown(0); // Sift down the new root element |
| 113 | + return peeked; |
| 114 | + } |
| 115 | + |
| 116 | + public void insert(int value) { |
| 117 | + if (size >= heap.length) { |
| 118 | + heap = Arrays.copyOf(heap, size * 2); // Resize the array if necessary |
| 119 | + } |
| 120 | + heap[size] = value; // Append the new element to the end of the heap |
| 121 | + size++; |
| 122 | + siftUp(); // Sift up the new element to its correct position |
| 123 | + } |
| 124 | + |
| 125 | + private void swap(int i, int j) { |
| 126 | + int temp = heap[i]; |
| 127 | + heap[i] = heap[j]; |
| 128 | + heap[j] = temp; // Swap elements at indices i and j |
| 129 | + } |
| 130 | + |
| 131 | + public int length() { |
| 132 | + return size; // Return the number of elements in the heap |
| 133 | + } |
| 134 | +} |
| 135 | + |
| 136 | +public class Main { |
| 137 | + public static void main(String[] args) { |
| 138 | + int[] array = { 9, 4, 7, 1, -2, 6, 5 }; |
| 139 | + MinHeap minHeap = new MinHeap(array); |
| 140 | + |
| 141 | + System.out.println("Peek: " + minHeap.peek()); |
| 142 | + System.out.println("Remove: " + minHeap.remove()); |
| 143 | + System.out.println("Length: " + minHeap.length()); |
| 144 | + |
| 145 | + minHeap.insert(2); |
| 146 | + minHeap.insert(-5); |
| 147 | + |
| 148 | + System.out.println("Peek: " + minHeap.peek()); |
| 149 | + System.out.println("Length: " + minHeap.length()); |
| 150 | + } |
| 151 | +} |
0 commit comments