From ecccc5c6fdc1baee79c6216e1091f02d2299779e Mon Sep 17 00:00:00 2001 From: riyabansal98 Date: Tue, 15 Oct 2019 20:59:32 +0530 Subject: [PATCH] Fix: Modified Sorting notes --- Sorting/1.md | 169 ++++++++++++++++++++++++++++----------------------- Sorting/2.md | 149 ++++++--------------------------------------- Sorting/3.md | 138 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+), 207 deletions(-) create mode 100644 Sorting/3.md diff --git a/Sorting/1.md b/Sorting/1.md index 24b0382..6418891 100644 --- a/Sorting/1.md +++ b/Sorting/1.md @@ -1,25 +1,36 @@ # Sorting -- define sorting: permuting the sequence to enforce order. todo -- brute force: $O(n! \times n)$ +- Define sorting: permuting the sequence to enforce some order. +- Brute force Approach: $O(n! \times n)$. +Here n! is for finding out all the permutations for a list of number and n is for traversing all the permutations to pick the relevant one. -Stability ---------- -- definition: if two objects have the same value, they must retain their original order after sort -- importance: - - preserving order - values could be orders and chronological order may be important - - sorting tuples - sort on first column, then on second column --- -- +## Sorting Terminologies + +__Stability__ +- __Definition__: A sorting algorithm is said to be stable if two objects with equal keys appear in the same order in sorted output as they appear in the input array to be sorted. +- __Importance:__ + - preserving order - values could be orders and chronological order may be important. + - sorting tuples - sort on first column, then on second column. s + +- __Example__: Bubble Sort, Insertion Sort, Selection Sort etc. + +__In-Place Sorting__ + +- __Definition__: In-Place Sorting algorithms uses constant extra space to produce the output.
+- **Example:** Insertion Sort, Selection Sort + Insertion Sort -------------- -- explain: - - 1st element is sorted - - invariant: for i, the array uptil i-1 is sorted - - take the element at index i, and insert it at correct position -- pseudo code: +**Explain:**
+- 1st element is sorted. +- Invariant: for i, the array uptil i-1 is sorted. +- Take the element at index i, and insert it at correct position. + +**Pseudo code:** + ```c++ void insertionSort(int arr[], int length) { int i, j, key; @@ -34,52 +45,91 @@ Insertion Sort } } ``` -- **Stablility:** Stable, because swap only when strictly >. Had it been >=, it would be unstable +- **Stablility:** Yes Stable, because swap only when strictly >. Had it been >=, it would be unstable +- **In Place Sorting** - **Complexity:** $O(n^2)$ - --- -- - +- **Auxiliary Space:** O(1) +- **Boundary Cases:** Insertion sort takes maximum time to sort if elements are sorted in reverse order. And it takes minimum time (Order of n) when elements are already sorted. +- **Uses:** Insertion sort is used when number of elements is small. It can also be useful when input array is almost sorted, only few elements are misplaced in complete big array. Bubble Sort ----------- -- explain: - - invariant: last i elements are the largest one and are in correct place. -- why "bubble": largest unsorted element bubbles up - just like bubbles -- pseudo code: +**Explain:** + +- Invariant: last i elements are the largest one and are in correct place. +- Why "bubble": largest unsorted element bubbles up - just like bubbles. +- Works by repeatedly swapping the adjacent elements if they are in wrong order. + +**Pseudo code:** + ```c++ void bubbleSort(int arr[], int n) { for (int i = 0; i < n-1; i++) - for (int j = 0; j < n-i-1; j++) - if (arr[j] > arr[j+1]) - swap(&arr[j], &arr[j+1]); + for (int j = 0; j < n-i-1; j++) + if (arr[j] > arr[j+1]) + swap(&arr[j], &arr[j+1]); } + ``` - **Stability:** Stable -- **Complexity:** $O(n^2)$ - --- -- +- **Complexity:** $O(n^2)$ ( Worst Case ) $O(n)$ Best Case +- **Auxiliary Space:** O(1) +- **In Place Sorting** +- **Boundary Cases:** Bubble sort takes minimum time ( Order n ) when elements are already sorted. Bubble Sort with window of size 3 --------------------------------- -- explain bubble sort as window of size 2 -- propose window of size 3 -- does this work? -- no - even and odd elements are never compared - --- -- +- Explain bubble sort as window of size 2 +- Propose window of size 3 +- Does this work? +- No - even and odd elements are never compared +Selection Sort +----- + +**Explain** +- Works by repeatedly finding the minimum element from unsorted part and putting it at the beginning. +- The algorithm maintains two subarrays in a given array. + - The subarray which is already sorted. + - Remaining subarray which is unsorted. +- In every iteration of selection sort, the minimum element from the unsorted subarray is picked and moved to the sorted subarray. + +**PseudoCode** +```c++ +void selectionSort(int arr[], int n) +{ + int i, j, min_idx; + + // One by one move boundary of unsorted subarray + for (i = 0; i < n-1; i++) + { + // Find the minimum element in unsorted array + min_idx = i; + for (j = i+1; j < n; j++) + if (arr[j] < arr[min_idx]) + min_idx = j; + + // Swap the found minimum element with the first element + swap(&arr[min_idx], &arr[i]); + } +} +``` + +**Time Complexity**: $O(n^2)$
+**Space Complexity**: O(1) Counting Sort ------------- -- explain: - - given array, first find min and max in O(n) time - - create space of O(max-min) - - count the number of elements - - take prefix sum -- constraint: can only be used when the numbers are bounded. -- pseudo code: +**Explain:** +- Given array, first find min and max in O(n) time. +- Create space of O(max-min) +- Count the number of elements +- Take prefix sum +- _Constraint_: can only be used when the numbers are bounded. + +**Pseudo code:** ```c++ void counting_sort(char arr[]) { // find min, max @@ -94,22 +144,9 @@ Counting Sort } ``` - **Stability:** Stable, if imlpemented correctly -- **Complexity**: $O(n + \max(a[i]))$ +- **Time Complexity**: $O(n + \max(a[i]))$ - why not just put the element there? if numbers/value, can do. Else, could be objects - --- -- - - -Radix Sort ----------- -- sort elements from lowest significant to most significant values -- explain: basically counting sort on each bit / digit -- **Stability:** inherently stable - won't work if unstable -- **complexity:** $O(n \log\max a[i])$ - --- -- - - +- **Space Complexity**: $O(n + \max(a[i]))$ Partition Array --------------- @@ -130,23 +167,3 @@ good: {1, 2}, {3, 4, 5} -- -- - -Sex-Tuples ----------- -> Given A[n], all distinct -> find the count of sex-tuples such that -> $$\frac{a b + c}{d} - e = f$$ -> Note: numbers can repeat in the sextuple - -- Naive: ${n \choose 6} = O(n^6)$ -- Optimization. Rewrite the equation as $ab + c = d(e + f)$ - - Now, we only need ${n \choose 3} = O(n^3)$ - - Caution: $d \neq 0$ - - Once you have array of RHS, sort it in $O(\log n^3)$ time. - - Then for each value of LHS, count using binary search in the sorted array in $\log n$ time. - - Total: $O(n^3 \log n)$ - --- -- - -Anagrams --------- diff --git a/Sorting/2.md b/Sorting/2.md index 3479b5b..8ce1268 100644 --- a/Sorting/2.md +++ b/Sorting/2.md @@ -1,139 +1,26 @@ - -# Sorting 2 --- -- - -Merge Sort +Radix Sort ---------- -- Divide and Conquer - - didive into 2 - - sort individually - - combine the solution -- Merging takes $O(n+m)$ time. - - needs extra space -- code for merging: - ```c++ - // arr1[n1] - // arr2[n2] - int i = 0, j = 0, k = 0; - - // output[n1+n2] - - while (i 2 sorted arrays -> ``` -> 1 2 2 3 4 9 -> 2 3 3 9 9 -> -> intersection: 2 3 9 -> ``` -- calculate intersection. Report an element only once -- Naive: - - Search each element in the other array. $O(n \log m)$ -- Optimied: - - Use merge. - - Ignore unequal. - - Add equal. - - Move pointer ahead till next element +Sex-Tuples +---------- +> Given A[n], all distinct +> find the count of sex-tuples such that +> $$\frac{a b + c}{d} - e = f$$ +> Note: numbers can repeat in the sextuple --- -- +- Naive: ${n \choose 6} = O(n^6)$ +- Optimization. Rewrite the equation as $ab + c = d(e + f)$ + - Now, we only need ${n \choose 3} = O(n^3)$ + - Caution: $d \neq 0$ + - Once you have array of RHS, sort it in $O(\log n^3)$ time. + - Then for each value of LHS, count using binary search in the sorted array in $\log n$ time. + - Total: $O(n^3 \log n)$ - -Merging without extra space ---------------------------- -- can use extra time -- if a[i] < b[j], i++ -- else: swap put b[i] in place of a[i]. Sorted insert a[i] in b array -- so, $O(n^2)$ time - - --- -- - - -Count inversions ---------------- -> inversion: -> i < j, but a[i] > a[j] (strict inequalities) -- naive: $O(n^2)$ -- Split array into 2. -- Number of inversions = number of inversions in A + B + cross terms -- count the cross inversions by example -- does number of cross inversions change when sub-arrays are permuted? -- no -- can we permute so that it becomes easier to count cross inversions? -- sort both subarrays and count inversions in A, B recursively -- then, merge A and B and during the merge count the number of inversions -- A_i B_j -- if A[i] > B[j], then there are inversions -- num inversions for A[i], B[j] = |A| - i -- intra array inversions? Counted in recursive case. - - --- -- - - -Find doubled-inversions ------------------------ -> same as inversion -> just i < j, a[i] > 2 * a[j] - -- same as previous. Split and recursilvely count -- while merging, for some b[j], I need to find how many elements in A are greater than 2 * b[j] -- linear search for that, but keep index -- linear search is better than binary search - - --- -- - -Sort n strings of length n each - - $T(n) = 2T(n/2) + O(n^2) = O(n^2)$ is wrong - - $T(n) = 2T(n/2) + O(n) * O(m) = O(nm\log n)$ is correct. Here m = the initial value of n - - --- -- -> . -> -> I G N O R E -> -> . - - -Bounded Subarray Sum Count --------------------------- -> given A[N] -> can have -ve -> given lower <= upper -> find numbe of subarrays such that lower <= sum <= upper - -- naive: $O(n^2)$ (keep prefix sum to calculate sum in O(1), n^2 loop) -- if only +ve, $O(n\log n)$ using prefix sum -- but what if -ve? -- - - --- -- diff --git a/Sorting/3.md b/Sorting/3.md new file mode 100644 index 0000000..619fa9b --- /dev/null +++ b/Sorting/3.md @@ -0,0 +1,138 @@ + +# Sorting 3 + +Merge Sort +---------- +- Divide and Conquer + - didive into 2 + - sort individually + - combine the solution +- Merging takes $O(n+m)$ time. + - needs extra space +- code for merging: + ```c++ + // arr1[n1] + // arr2[n2] + int i = 0, j = 0, k = 0; + + // output[n1+n2] + + while (i 2 sorted arrays +> ``` +> 1 2 2 3 4 9 +> 2 3 3 9 9 +> +> intersection: 2 3 9 +> ``` +- calculate intersection. Report an element only once +- Naive: + - Search each element in the other array. $O(n \log m)$ +- Optimied: + - Use merge. + - Ignore unequal. + - Add equal. + - Move pointer ahead till next element + + +-- -- + + +Merging without extra space +--------------------------- +- can use extra time +- if a[i] < b[j], i++ +- else: swap put b[i] in place of a[i]. Sorted insert a[i] in b array +- so, $O(n^2)$ time + + +-- -- + + +Count inversions +--------------- +> inversion: +> i < j, but a[i] > a[j] (strict inequalities) +- naive: $O(n^2)$ +- Split array into 2. +- Number of inversions = number of inversions in A + B + cross terms +- count the cross inversions by example +- does number of cross inversions change when sub-arrays are permuted? +- no +- can we permute so that it becomes easier to count cross inversions? +- sort both subarrays and count inversions in A, B recursively +- then, merge A and B and during the merge count the number of inversions +- A_i B_j +- if A[i] > B[j], then there are inversions +- num inversions for A[i], B[j] = |A| - i +- intra array inversions? Counted in recursive case. + + +-- -- + + +Find doubled-inversions +----------------------- +> same as inversion +> just i < j, a[i] > 2 * a[j] + +- same as previous. Split and recursilvely count +- while merging, for some b[j], I need to find how many elements in A are greater than 2 * b[j] +- linear search for that, but keep index +- linear search is better than binary search + + +-- -- + +Sort n strings of length n each + - $T(n) = 2T(n/2) + O(n^2) = O(n^2)$ is wrong + - $T(n) = 2T(n/2) + O(n) * O(m) = O(nm\log n)$ is correct. Here m = the initial value of n + + +-- -- +> . +> +> I G N O R E +> +> . + + +Bounded Subarray Sum Count +-------------------------- +> given A[N] +> can have -ve +> given lower <= upper +> find numbe of subarrays such that lower <= sum <= upper + +- naive: $O(n^2)$ (keep prefix sum to calculate sum in O(1), n^2 loop) +- if only +ve, $O(n\log n)$ using prefix sum +- but what if -ve? +- + + +-- --