Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions Exercise_1.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
class BinarySearch {
// Time Complexity : O(log n)
// Space Complexity : O(n) just for the array
// Your code here along with comments explaining your approach
/*
* I try to find the mid element iteratively until my left value gets less than or equal to right index
* If I find my target element dorectly at mid index, I return it, if not, I compare the value of target
* with value of mid to see and move my left, right indices to narrow the search criteria. Return -1 if
* target not found.
* */

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 - l) / 2;
if(x == arr[mid])
return mid;
else if(arr[mid] < x)
l = mid + 1;
else
r = mid - 1;
}
return -1;
}

// Driver method to test above
Expand All @@ -11,7 +31,7 @@ public static void main(String args[])
BinarySearch ob = new BinarySearch();
int arr[] = { 2, 3, 4, 10, 40 };
int n = arr.length;
int x = 10;
int x = 10;
int result = ob.binarySearch(arr, 0, n - 1, x);
if (result == -1)
System.out.println("Element not present");
Expand Down
37 changes: 33 additions & 4 deletions Exercise_2.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
class QuickSort
// Time Complexity : O(nlog n) best and average case , O(n^2) worst case
// Space Complexity : O(n) worst case
// Your code here along with comments explaining your approach
/*
* The idea is to find a specific partition index and sort using it for first and second halfs recursively
* But, to choose this partition, I need to understand the order of the elements. So, I assume a pivot
* element first, then try to compare iteratively each element of the array with pivot and make sure to
* place/swap all those smaller elements to left side of the array in comparison with pivot. then, I return
* that least index element which acts as a partition of smaller sorted elements till now and the rest.
* */
class QuickSort
{
/* This function takes last element as pivot,
places the pivot element at its correct
Expand All @@ -7,12 +17,26 @@ class QuickSort
pivot and all greater elements to right
of pivot */
void swap(int arr[],int i,int j){
//Your code here
//Your code here
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

int partition(int arr[], int low, int high)
{
//Write code here for Partition and Swap
//Write code here for Partition and Swap
int i = low - 1;
int pivot = arr[high];

for(int j = low ; j <= high - 1 ; j++) {
if(arr[j] < pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return i + 1;
}
/* The main function that implements QuickSort()
arr[] --> Array to be sorted,
Expand All @@ -21,7 +45,12 @@ int partition(int arr[], int low, int high)
void sort(int arr[], int low, int high)
{
// Recursively sort elements before
// partition and after partition
// partition and after partition
if(low < high) {
int pi = partition(arr, low, high);
sort(arr, low, pi - 1);
sort(arr, pi + 1, high);
}
}

/* A utility function to print array of size n */
Expand Down
20 changes: 19 additions & 1 deletion Exercise_3.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
class LinkedList
// Time Complexity : O(n)
// Space Complexity : O(1)

// Your code here along with comments explaining your approach
/*
I take 2 pointers fast and slow and make sure to move fast pointer quickly and slow pointer just behind
it to fetch the exact middle element.
*/
class LinkedList
{
Node head; // head of linked list

Expand All @@ -20,6 +28,16 @@ void printMiddle()
{
//Write your code here
//Implement using Fast and slow pointers
if(head == null) {
System.out.println("List is empty");
}
Node slow = head;
Node fast = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
System.out.println("Middle elmement is " + slow.data);
}

public void push(int new_data)
Expand Down
44 changes: 41 additions & 3 deletions Exercise_4.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,57 @@
class MergeSort
// Time Complexity : O(nlog n)
// Space Complexity : O(n) worst case
// Your code here along with comments explaining your approach
/*
* The idea is to split and sort left and right sub arrays recursively first and then eventually merge
* using 2 pointers making sure to pick smaller element each time, placing it in main array.
* */
class MergeSort
{
// Merges two subarrays of arr[].
// First subarray is arr[l..m]
// Second subarray is arr[m+1..r]
void merge(int arr[], int l, int m, int r)
{
//Your code here
//Your code here
int n1 = m - l + 1;
int n2 = r - m;

int[] N1 = new int[n1];
int[] N2 = new int[n2];

for(int i = 0 ; i < n1 ; i++)
N1[i] = arr[l + i];
for(int j = 0 ; j < n2 ; j++)
N2[j] = arr[m + 1 + j];

int i = 0, j = 0 , k = l;

while(i < n1 && j < n2) {
if(N1[i] < N2[j]) {
arr[k++] = N1[i++];
}
else
arr[k++] = N2[j++];
}
while(i < n1)
arr[k++] = N1[i++];
while(j < n2)
arr[k++] = N2[j++];
}

// Main function that sorts arr[l..r] using
// merge()
void sort(int arr[], int l, int r)
{
//Write your code here
//Call mergeSort from here
//Call mergeSort from here
if(l < r) {
int m = l + (r - l) / 2;
sort(arr, l, m);
sort(arr, m + 1, r);

merge(arr, l , m , r);
}
}

/* A utility function to print array of size n */
Expand Down
50 changes: 48 additions & 2 deletions Exercise_5.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,66 @@
class IterativeQuickSort {
// Time Complexity : O(nlog n)
// Space Complexity : O(n)
// Your code here along with comments explaining your approach
/*
* The idea is to use the same partition logic, but instead of recursion, use a stack logic to store (l,h) pairs of
* subarrays.Each iteration pops a subarray, partitions it and pushes left/right subarrays
* Instead of extra variable, I used XOR logic to swap
* */
class IterativeQuickSort {
void swap(int arr[], int i, int j)
{
//Try swapping without extra variable
//Try swapping without extra variable
if(i != j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
}

/* This function is same in both iterative and
recursive*/
int partition(int arr[], int l, int h)
{
//Compare elements and swap.
int i = l - 1;
int pivot = arr[h];

for(int j = l ; j < h ; j++) {
if(arr[j] <= pivot) {
i++;
swap(arr, i , j);
}
}
swap(arr, i + 1, h);
return i + 1;
}

// 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(l < p - 1) {
stack[++top] = l;
stack[++top] = p - 1;
}
if(p + 1 < h) {
stack[++top] = p + 1;
stack[++top] = h;
}
}


}

// A utility function to print contents of arr
Expand Down