From fba9a94bceee48c2d375f877334e8d012a99f913 Mon Sep 17 00:00:00 2001 From: angadsingh Date: Sun, 19 Jul 2026 02:48:11 -0400 Subject: [PATCH] completed comp-coding-01 --- 01-missing-num-in-sorted-array.cpp | 34 ++++++ 02-implement-min-heap.cpp | 160 +++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 01-missing-num-in-sorted-array.cpp create mode 100644 02-implement-min-heap.cpp diff --git a/01-missing-num-in-sorted-array.cpp b/01-missing-num-in-sorted-array.cpp new file mode 100644 index 00000000..43fd2b63 --- /dev/null +++ b/01-missing-num-in-sorted-array.cpp @@ -0,0 +1,34 @@ +/* +TC - O(logN) for the binary search performed +SC - O(1) +Issues Faced - Yes, could not develop intuition for moving within binary search after getting the missing number count. +Now I understand that we wish to get to the closest point possible where missing number count is lt/eq to k, and from that point on we can extrapolate the missing numbers in constant time. The advantage is that this beats a linear O(n) scan. + +Run on leetcode - no, since I do not have premium access. + +*/ + +class Solution { + public: + int missingElement(vector& nums, int k) { + + int n = nums.size(); + int lo = 0; + int hi = n - 1; + + while (lo <= hi) { + int mid = (lo + (hi - lo)/2); + int missingNumbers = nums[mid] - nums[0] - mid; + if (missingNumbers >= k) { //equal to is important, move left to find that inflection point + hi = mid - 1; + } else { + lo = mid + 1; + } + } + + //at the end of this, we would be at the index where the missing numbers are lesser than or equal to the given k + int stillMissingAtHi = nums[hi] - nums[0] - hi; + return nums[hi] + (k - stillMissingAtHi); + } + }; + \ No newline at end of file diff --git a/02-implement-min-heap.cpp b/02-implement-min-heap.cpp new file mode 100644 index 00000000..538beecb --- /dev/null +++ b/02-implement-min-heap.cpp @@ -0,0 +1,160 @@ +/* +TC - O(logN) for push/pop, O(N) for heapify +SC - O(N) to hold the elements +*/ + + +/* +Issues Faced with CPP Syntax - Need to Improve + +- class syntax is rusty +- declared access specifiers but not entirely sure I have written it in Java style or not. Pretty sure it is C++ style though. +- can I put function prototypes and the implementations in the class itself? or do prototypes go inside and I use scope resolution operators to resolve and implement outside? +- is a minHeap only for integers? how do I templatize this? Should I do this, given an interview situation? Probably better to ask the interviewer. +- I forgot that I need a constructor and destructor for this + +*/ + +/* + +Issues faced with Min Heap Implementation +- what are the internal data structures a heap holds? +- an array or a vector? does it matter? yes, probably does in terms of ease of dynamic resizing. + +*/ + + +class minHeap { + private: + vector heapData; + + public: + int heapPop() { + if (heapData.size() == 0) { + return -1; + } + int poppedValue = heapData[0]; + + heapData[0] = heapData.back(); + heapData.pop_back(); + + int n = heapData.size(); + int currParent = 0; + + while (2*currParent + 1 < n) { + int leftChild = 2 * currParent + 1; + int rightChild = 2 * currParent + 2; + int smallest = currParent; + + if (heapData[leftChild] < heapData[smallest]) { + smallest = leftChild; + } + if (rightChild < n && heapData[rightChild] < heapData[smallest]) { + smallest = rightChild; + } + + if (smallest != currParent) { + swap(heapData[smallest], heapData[currParent]); + currParent = smallest; // Move down further to fix this now + } else { + break; // we have placed it + } + + } + + return poppedValue; + + + } + + void heapPush(int x) { + heapData.push_back(x); + int i = heapData.size() - 1; + while (i != 0) { + int parentNode = (i-1)/2; + + if (heapData[i] < heapData[parentNode]) { + swap(heapData[i], heapData[parentNode]); + i = parentNode; + } else { + //placed correctly, can break + break; + } + + } + } + + + // minHeap(int* arr, int size); >> you do NOT keep prototypes and declarations in the same scope. Could take the + //latter out using SRO though + ~minHeap() { + + } + + // void heapify(vector &arr) { >> no need to pass it, we already have it in the class + //this is floyd's algorithm - uses bottom-up approach in O(N) + //Faster than inserting elements one by one, which is O(NlogN) + void heapify() { + int n = heapData.size(); + //start at the last non-leaf node + if (heapData.size() == 0) { + return; + } + + int smallestChild = (n/2) - 1; + + //iterate backwards to the root + + for (int i = smallestChild ; i >= 0; i--) { + //sift down node i, while it has at least one child to compare to + /* + - look at the current parent node and its two children + - find the smallest value amoung the three + - swap the parent with that smallest value, if the child is smaller + - repeat this process at the new child position until the parent is smaller than both its children, or becomes a leaf + */ + + int currParent = i; + while (2 * currParent + 1 < n) { //While a left child exists + int leftChild = 2*currParent + 1; + int rightChild = 2*currParent + 2; + int smallest = currParent; + + if (heapData[leftChild] < heapData[smallest]) { + smallest = leftChild; + } + + if (rightChild < n && heapData[rightChild] < heapData[smallest]) { + smallest = rightChild; + } + + if (smallest != currParent) { //something was smaller + swap(heapData[smallest], heapData[currParent]); //swap them! + currParent = smallest; //moves us down the tree + } else { + break;//no more sifting since we are in the right spot + } + + } + + } + + //sift/percolate down each node + //find the smallest child + //compare with parent + //repeat down the tree + + } + + minHeap(int* arr, int size){ + //how do I iterate over this? + //sizeof will not work because this pointer has been flattened, so I will get the sizeof the integer pointer instead + //isn't size a reserved keyword? + for (int i = 0; i< size; i++) { + heapData.push_back(arr[i]); + } + heapify(); + } + + +};