diff --git a/Problem1.java b/Problem1.java index 8b137891..8b39a3bf 100644 --- a/Problem1.java +++ b/Problem1.java @@ -1 +1,62 @@ +//Problem: Finding missing number in a sorted array + +class Main { + /** + * Approach 1: This method uses the property that in a sorted array starting from a specific value, + * the difference between the element and its index (nums[i] - i) should remain constant. + * If a number is missing, this difference will change for all elements after the gap. + * + * Time Complexity: O(log N) - Standard binary search where the search space is halved in each step. + * Space Complexity: O(1) - Only a few variables are used regardless of input size. + */ + + private static int search(int[] nums){ + + int low = 0; + int high = nums.length -1; + + while(high - low > 1){ + int mid = low + (high - low)/2; + if(nums[mid] - mid == nums[low] - low){ + low = mid; + }else{ + high = mid; + } + } + return (nums[low] + nums[high])/2; + } + + /** + * Approach 2 : This method checks if the current element (arr[mid]) is exactly one greater + * than its predecessor. If it is, the sequence is intact up to that point, so we + * search the right half. Otherwise, the break occurred earlier, so we search the left. + * + * Time Complexity: O(log N) - Each iteration reduces the search range by half. + * Space Complexity: O(1) - Constant space used for pointers. + */ + + private static int search2(int[] arr){ + + int low = 0; + int high = arr.length-1; + + while(high - low > 1){ + int mid = low + (high - low)/2; + if(arr[mid] == arr[mid - 1] + 1){ + low = mid; + }else{ + high = mid; + } + } + + + return arr[low]+1; + } + public static void main(String[] args) { + int[] nums = { 2,3,4,5,6,7,9}; + + System.out.println("Missing number: " + search(nums)); + //System.out.println("Missing number: " + search2(nums)); + } +} diff --git a/Problem2.java b/Problem2.java index 8b137891..4840a948 100644 --- a/Problem2.java +++ b/Problem2.java @@ -1 +1,121 @@ +package Heap; +public class BinaryMinHeap { + int heapArray[]; + int size; + + //Time Complexity: O(1) + //Space Complexity: O(N) + // Constructor initializes the heap with a given capacity. + // We use a 1-based indexing for easier parent-child relationship calculations. + + public BinaryMinHeap(int capacity){ + this.size = 0; + this.heapArray = new int[capacity+1]; + System.out.println(" Binary Heap of size " + capacity + " has been created"); + } + //Time Complexity: O(1) + //Space Complexity: O(1) + // Checks if the heap contains any elements by verifying the current size. + public boolean isEmpty(){ + return size == 0; + } + //Time Complexity: O(1) + //Space Complexity: O(1) + //Returns the root element (minimum) without removing it. + //In a min-heap, the minimum value is always at index 1. + public Integer peek(){ + if(isEmpty()){ + System.out.println("The Heap is Empty."); + return null; + } + return heapArray[1]; + } + //Time Complexity: O(1) + //Space Complexity: O(1) + //Returns the current number of elements in the heap. + public int sizeOfHeap(){ + return size; + } + + //Time Complexity: O(N) + //Space Complexity: O(1) + //Iterates through the array from index 1 to size to print elements + // in the order they appear in the heap's array representation. + public void levelOrderTraversal(){ + for(int i=1; i<=size; i++){ + System.out.print(heapArray[i] + " "); + } + System.out.println(""); + } + //Time Complexity: O(logN) + //Space Complexity: O(logN) + //Inserts a new value at the end of the heap (next available leaf) + //and then bubbles it up to restore the min-heap property. + public void insert(int value){ + heapArray[++size] = value; + heapifyBottomUp(size); + } + //Time Complexity: O(logN) + //Space Complexity: O(logN) + //Maintains min-heap property by comparing the current node with its parent. + //If the current node is smaller, they are swapped, and the process continues upward. + public void heapifyBottomUp(int index){ + int parent = index/2; + // base condition + if(index <= 1){ + return; + } + //swap condition for min heap + if(heapArray[index] < heapArray[parent]){ + int temp = heapArray[index]; + heapArray[index] = heapArray[parent]; + heapArray[parent] = temp; + } + heapifyBottomUp(parent); + } + + //Time Complexity: O(logN) + //Space Complexity: O(logN) + //Maintains min-heap property by comparing the current node with its children. + //If a child is smaller than the parent, it swaps with the smaller child and continues downward. + public void heapifyToptoBottom(int index){ + + int leftChild = 2*index; + int rightChild = 2*index + 1; + + if(leftChild <= size && heapArray[leftChild] < heapArray[index]){ + int temp = heapArray[leftChild]; + heapArray[leftChild] = heapArray[index]; + heapArray[index] = temp; + heapifyToptoBottom(leftChild); + }else if(rightChild <= size && heapArray[rightChild] < heapArray[index]){ + int temp = heapArray[rightChild]; + heapArray[rightChild] = heapArray[index]; + heapArray[index] = temp; + heapifyToptoBottom(rightChild); + } + } + + //Time Complexity: O(logN) + //Space Complexity: O(logN) + //Removes and returns the minimum element (root). + //The last element in the heap replaces the root, the size is decremented, + //and heapifyToptoBottom is called to restore the heap property. + public int extractMin(){ + if(isEmpty()){ + return -1; + } + int extractedValue = heapArray[1]; + heapArray[1] = heapArray[size--]; + heapifyToptoBottom(1); + return extractedValue; + } + + //Time Complexity: O(1) + //Space Complexity: O(1) + public void deleteHeap(){ + heapArray = null; + System.out.println(); + } +}