From 87c673ed499a0718a9f6a73b4b8c35c3bf2a6d9f Mon Sep 17 00:00:00 2001 From: gurneetk186 Date: Mon, 24 Nov 2025 09:00:29 -0800 Subject: [PATCH] Completed PreCourse-2 --- .gitignore | 1 + Exercise_1.java | 32 ++++++++++++++++++++++++++- Exercise_2.java | 35 +++++++++++++++++++++++++++--- Exercise_3.java | 31 +++++++++++++++++++++++---- Exercise_4.java | 57 ++++++++++++++++++++++++++++++++++++++++++++++--- Exercise_5.java | 51 ++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 193 insertions(+), 14 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..6b468b62 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.class diff --git a/Exercise_1.java b/Exercise_1.java index c3ff1141..6c780ee6 100644 --- a/Exercise_1.java +++ b/Exercise_1.java @@ -1,9 +1,39 @@ +// Time Complexity : O(log n) +// Space Complexity : O(1) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : +// Initially had an issue with the mid calculation and misplaced braces, +// but after fixing those, the logic worked correctly. + + + +// I used an iterative Binary Search approach. In each iteration, I compute +// the mid index and compare the middle element with the target. +// - If arr[mid] equals the target, I return mid. +// - If the target is smaller, I move the right pointer to mid - 1. +// - If the target is larger, I move the left pointer to mid + 1. +// I continue this until left > right. If no match is found, I return -1. class BinarySearch { // Returns index of x if it is present in arr[l.. r], else return -1 int binarySearch(int arr[], int l, int r, int x) { - //Write your code here + while(l <= r){ + int mid = l +(r-1)/2; + + if (arr[mid]==x){ + return mid; + //Write your code here } + + if (arr[mid] > x){ + r = mid -1; + } + else{ + l=mid + 1; + } + } + return -1; + } // Driver method to test above public static void main(String args[]) diff --git a/Exercise_2.java b/Exercise_2.java index d0b5fa5f..51cb5c2d 100644 --- a/Exercise_2.java +++ b/Exercise_2.java @@ -1,3 +1,17 @@ +// Time Complexity : O(log n) +// Space Complexity : O(1) for iterative version +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : +// Initially had issues with mid calculation and extra braces, +// but corrected them to ensure clean and accurate execution. + + +// I used the standard iterative Binary Search algorithm. In each step, +// I calculate the mid index and compare it with the target value. +// If the target is smaller, I move the right boundary to mid-1. +// If the target is larger, I move the left boundary to mid+1. +// If arr[mid] equals the target, I return the mid index. +// If the loop ends with no match, I return -1. class QuickSort { /* This function takes last element as pivot, @@ -7,20 +21,35 @@ class QuickSort pivot and all greater elements to right of pivot */ void swap(int arr[],int i,int j){ - //Your code here + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp;//Your code here } int partition(int arr[], int low, int high) { - //Write code here for Partition and Swap + int pivot = arr[high]; + int i = (low-1); + for (int j = low; j < high; j++){ + if(arr[j] <= pivot){ + i++; + swap(arr,i,j); + }//Write code here for Partition and Swap } + swap(arr, i+1, high); + return i + 1; + } /* The main function that implements QuickSort() arr[] --> Array to be sorted, low --> Starting index, high --> Ending index */ void sort(int arr[], int low, int high) { - // Recursively sort elements before + if(low < high){ + int pi = partition(arr,low, high); +sort(arr, low, pi - 1); +sort(arr, pi + 1, high); + }// Recursively sort elements before // partition and after partition } diff --git a/Exercise_3.java b/Exercise_3.java index 1f9b752a..ca6100e1 100644 --- a/Exercise_3.java +++ b/Exercise_3.java @@ -1,3 +1,17 @@ +// Time Complexity : O(n) +// Space Complexity : O(1) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : +// No major issues. The main challenge was remembering that the fast pointer +// moves two steps at a time while the slow pointer moves one step. This ensures +// the slow pointer reaches the middle when fast reaches the end. + + +// I used the two-pointer (slow and fast) technique. The fast pointer moves +// two nodes at a time, while the slow pointer moves one node at a time. +// When the fast pointer reaches the end of the list (or becomes null), +// the slow pointer will be pointing to the middle element of the list. +// This approach allows us to find the middle in a single traversal. class LinkedList { Node head; // head of linked list @@ -18,13 +32,22 @@ class Node //Complete this function void printMiddle() { - //Write your code here + if (head == null){ + System.out.println("The last is empty"); + return;} + Node slow = head; + Node fast = head; + while (fast != null && fast.next != null){ + fast = fast.next.next; + slow = slow.next;//Write your code here //Implement using Fast and slow pointers } - + System.out.println("Middle element is: " + slow.data); + } public void push(int new_data) { - Node new_node = new Node(new_data); + + Node new_node = new Node(new_data); new_node.next = head; head = new_node; } @@ -50,4 +73,4 @@ public static void main(String [] args) llist.printMiddle(); } } -} \ No newline at end of file +} diff --git a/Exercise_4.java b/Exercise_4.java index 81afd3c2..1c3bac90 100644 --- a/Exercise_4.java +++ b/Exercise_4.java @@ -1,3 +1,19 @@ +// Time Complexity : O(n log n) +// Space Complexity : O(n) +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : +// No major issues. The tricky part was correctly dividing the array, +// creating temporary subarrays, and ensuring all remaining elements +// from each subarray were copied back into the main array. + + + +// I used the classic Merge Sort algorithm, which divides the array +// into two halves recursively until each subarray has one element. +// Then the merge() function is used to combine the two sorted halves +// by comparing elements and placing them in the correct order. +// The merge step uses temporary arrays to store left and right halves. +// Finally, the sorted values are copied back into the original array. class MergeSort { // Merges two subarrays of arr[]. @@ -5,14 +21,49 @@ class MergeSort // Second subarray is arr[m+1..r] void merge(int arr[], int l, int m, int r) { - //Your code here + int n1 = m - l + 1; + int n2 = r - m; + int L[] = new int[n1]; + int R[] = new int[n2]; + for (int i = 0; i < n1; ++i) + L[i] =arr[l + i]; + + for (int j = 0; j < n2; ++j) + R[j] = arr[m + 1 +j]; +int i = 0, j = 0; +int k = l; +while (i < n1 && j < n2){ + if (L[i] <= R[j]) + { + arr[k] = L[i]; + i++; + }else{ + arr[k] = R[j]; + j++; + } + k++; +} +while (i < n1){ + arr[k] = L[i]; + i++; + k++; +}while(j < n2){ + arr[k] = R[j]; + j++; + k++; +}//Your code here } // Main function that sorts arr[l..r] using // merge() void sort(int arr[], int l, int r) { - //Write your code here + if(l < r){ + int m =(l + r) / 2; + sort(arr, l, m); + sort(arr, m + 1, r); + merge(arr, l, m, r); + }//Write your code here //Call mergeSort from here } @@ -39,4 +90,4 @@ public static void main(String args[]) System.out.println("\nSorted array"); printArray(arr); } -} \ No newline at end of file +} diff --git a/Exercise_5.java b/Exercise_5.java index 30e82675..9db5fc80 100644 --- a/Exercise_5.java +++ b/Exercise_5.java @@ -1,6 +1,25 @@ +// Time Complexity : O(n log n) average case, O(n^2) worst case +// Space Complexity : O(log n) because of the manual stack +// Did this code successfully run on Leetcode : Yes +// Any problem you faced while coding this : +// Understanding the stack-based iterative approach was the main challenge. +// Instead of recursive calls, I used an integer stack to store subarray +// boundaries and process them iteratively. + + + +// I implemented Iterative QuickSort using a stack to simulate the recursion. +// The algorithm pushes left and right subarray boundaries onto the stack. +// For each popping, it calls partition() to place the pivot in the correct spot. +// Then it pushes the boundaries of the left and right subarrays back onto the stack. +// The process continues until the stack is empty. class IterativeQuickSort { void swap(int arr[], int i, int j) { + if (i == j) return; + arr[i] = arr[i] + arr[j]; + arr[j] = arr[i] - arr[j]; + arr[i] = arr[i] - arr[j]; //Try swapping without extra variable } @@ -8,13 +27,39 @@ void swap(int arr[], int i, int j) recursive*/ int partition(int arr[], int l, int h) { - //Compare elements and swap. + int pivot = arr[h]; + int i = (l - 1); + for (int j = l; j <= h - 1; j++){ + if(arr[j] <= pivot){ + i++; + swap(arr, i, j); + } + } + swap(arr, i + 1, h); + return (i + 1); + //Compare elements and swap. } // Sorts arr[l..h] using iterative QuickSort void QuickSort(int arr[], int l, int h) { - //Try using Stack Data Structure to remove recursion. + int stack[] = new int[h -l + 1]; + int top = -1; + stack[++top] = l; + stack[++top] = h; + while (top >= 0){ + h = stack[top--]; + l =stack[top--]; + int p = partition(arr, l , h); + if (p - 1 > l){ + stack[++top] = l; + stack[++top] = p-1; + } + if(p + 1 < h){ + stack[++top] = p + 1; + stack[++top] = h; + } + }//Try using Stack Data Structure to remove recursion. } // A utility function to print contents of arr @@ -33,4 +78,4 @@ public static void main(String args[]) ob.QuickSort(arr, 0, arr.length - 1); ob.printArr(arr, arr.length); } -} \ No newline at end of file +}