// ——————————————————————————————————————–
Guess What Algo
// ——————————————————————————————————————–
<===================~~==-----==()==-----==~~==========================>
// HINTS:
// divide and conquer // need a helper function that solves merging elements of two sorted arrays into a single sorted array
function guessWhatAlgo(array) {
if (array.length <= 1) {
return array;
}
let midIdx = Math.floor(array.length / 2);
let leftHalf = array.slice(0, midIdx);
let rightHalf = array.slice(midIdx);
let sortedLeft = guessWhatAlgo(leftHalf);
let sortedRight = guessWhatAlgo(rightHalf);
return helperguessWhatAlgo(sortedLeft, sortedRight);
}
// ANSWER: Merge sort
// if there is only one element in the list, it is already sorted.return that array. // otherwise, divide the list recursively into two halves until it can no more be divided. // merge the smaller lists into new list in sorted order.
// TIME COMPLEXITY: O(nlogn)
// SPACE COMPLEXITY:O(n)
<===================~~==-----==()==-----==~~==========================>
// HINT:
// works by performing multiple passes to move elements closer to their final positions
function guessWhatAlgo(array) {
let swapped = true;
while (swapped) {
// O(n)
swapped = false;
for (let i = 0; i < array.length; i++) {
//O(n)
if (array[i] > array[i + 1]) {
swap(array, i, i + 1);
swapped = true;
}
}
}
return array;
}
// ANSWER: Bubble sort
// TIME COMPLEXITY: O(n * n === n^2)
// SPACE COMPLEXITY: O(1)
<===================~~==-----==()==-----==~~==========================>
// HINT:
function guessWhatAlgo(array) {
if (array.length <= 1) {
return array;
}
let pivot = array.shift();
let left = array.filter((el) => el < pivot);
let right = array.filter((el) => el >= pivot);
let leftSorted = guessWhatAlgo(left);
let rightSorted = guessWhatAlgo(right);
return [...leftSorted, pivot, ...rightSorted];
}
// ANSWER: Quick sort
// TIME COMPLEXITY: worst case: O(n^2) best case: O(nlogn)
// SPACE COMPLEXITY:O(n)
<===================~~==-----==()==-----==~~==========================>
function guessWhatAlgo(arr) {
for (let i = 1; i < arr.length; i++) {
let currElement = arr[i];
for (var j = i - 1; j >= 0 && currElement < arr[j]; j--) {
arr[j + 1] = arr[j];
}
arr[j + 1] = currElement;
}
return arr;
}
// ANSWER: Insertion sort
// TIME COMPLEXITY: O(n^2)
// SPACE COMPLEXITY:O(1)
<===================~~==-----==()==-----==~~==========================>
function guessWhatAlgo(array, target) {
if (array.length === 0) {
return false;
}
let midIdx = Math.floor(array.length / 2);
if (target < array[midIdx]) {
let leftHalf = array.slice(0, midIdx);
return guessWhatAlgo(leftHalf, target);
} else if (target > array[midIdx]) {
let rightHalf = array.slice(midIdx + 1);
return guessWhatAlgo(rightHalf, target);
} else {
return true;
}
}
// ANSWER: Binary Search
// TIME COMPLEXITY: O(logn)
// SPACE COMPLEXITY:O(n) ]
<===================~~==-----==()==-----==~~==========================>
function guessWhatAlgo(arr) {
for (let i = 0; i < arr.length; i++) {
let minIndex = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
swap(arr, i, minIndex);
}
return arr;
}
// ANSWER: Selection sort
// TIME COMPLEXITY: O(n^2)
// SPACE COMPLEXITY:O(1)
// Use this pseudocode to implement the bubble sort function bubbleSort(array) { // n := length(array) // repeat // swapped = false // for i := 1 to n - 1 inclusive do // // /* if this pair is out of order / // if A[i - 1] > A[i] then // // / swap them and remember something changed */ // swap(A[i - 1], A[i]) // swapped := true // // end if // end for // until not swapped }
function swap(array, idx1, idx2) {
let temp = array[idx1]; // save a copy of the first value
array[idx1] = array[idx2]; // overwrite the first value with the second value
array[idx2] = temp; // overwrite the second value with the first value
}
function bubbleSort(array) {
// this variable will be used to track whether or not we
// made a swap on the previous pass. If we did not make
// any swap on the previous pass, then the array must
// already be sorted
let swapped = true;
// this while will keep doing passes if a swap was made
// on the previous pass
while (swapped) {
swapped = false; // reset swap to false
// this for will perform a single pass
for (let i = 0; i < array.length; i++) {
// if the two value are not ordered...
if (array[i] > array[i + 1]) {
// swap the two values
swap(array, i, i + 1);
// since you made a swap, remember that you did so
// b/c we should perform another pass after this one
swapped = true;
}
}
}
return array;
}
// Try to implement swap on your own, this time.
function swap(arr, index1, index2) {}
function selectionSort(list) {
// list : array of items
// n : size of list
//
// for i = 1 to n - 1
// /* set current element as minimum*/
// min = i
//
// /* check the element to be minimum */
//
// for j = i+1 to n
// if list[j] < list[min] then
// min = j;
// end if
// end for
//
// /* swap the minimum element with the current element
// using the above swap function*/
// if indexMin != i then
// swap list[min] and list[i]
// end if
// end for
}
function selectionSort(arr) {
// the `i` loop will track the index that points to the first element of the unsorted region:
// this means that the sorted region is everything left of index i
// and the unsorted region is everything to the right of index i
for (let i = 0; i < arr.length; i++) {
let minIndex = i;
// the `j` loop will iterate through the unsorted region and find the index of the smallest element
for (let j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
// after we find the minIndex in the unsorted region,
// swap that minIndex with the first index of the unsorted region
swap(arr, i, minIndex);
}
return arr;
}
function insertionSort(list) {
// for i from 1 to length(list) inclusive do:
// /* select value to be inserted */
// valueToInsert = list[i]
// holePosition = i
// /* locate hole position for the element to be inserted */
// while holePosition > 0 and list[holePosition-1] > valueToInsert do:
// list[holePosition] = list[holePosition-1]
// holePosition = holePosition -1
// end while
// /* insert the number at hole position */
// list[holePosition] = valueToInsert
// end for
}
// All 3 implementations work the same, just a reworking of syntax
// Insertion sort keeps a sorted left region working from left to right examining
// each item and comparing it to items on its left. It then inserts the item in
// the correct oposition in the array.
function insertionSortV2(arr) {
for (let i = 1; i < arr.length; i++) {
let j = i;
while (j > 0 && arr[j - 1] > arr[j]) {
swap(arr, j - 1, j);
j--;
}
}
return arr;
}
function swap(arr, index1, index2) {
let temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
// The version below swaps out the for loop for a while loop to avoid using var
function insertionSortV2(arr) {
// the `i` loop will iterate through every element of the array
// we begin at i = 1, because we can consider the first element of the array as a
// trivially sorted region of only one element
// insertion sort allows us to insert new elements anywhere within the sorted region
for (let i = 1; i < arr.length; i++) {
// grab the first element of the unsorted region
let currElement = arr[i];
// the `j` loop will iterate left through the sorted region,
// looking for a legal spot to insert currElement
let j = i - 1;
// keep moving left while currElement is less than the j-th element
while (j >= 0 && currElement < arr[j]) {
arr[j + 1] = arr[j];
// the line above will move the j-th element to the right,
// leaving a gap to potentially insert currElement
// we have to remember to decrement in our while loop!
j--;
}
// insert currElement into that gap
arr[j + 1] = currElement;
}
return arr;
}
// This solution utilizes var in the inner for loop to be able to use the variable
// after the loop exits. I generally try to avoid var because of the complications
// it can present.
function insertionSortV3(arr) {
// the `i` loop will iterate through every element of the array
// we begin at i = 1, because we can consider the first element of the array as a
// trivially sorted region of only one element
// insertion sort allows us to insert new elements anywhere within the sorted region
for (let i = 1; i < arr.length; i++) {
// grab the first element of the unsorted region
let currElement = arr[i];
// the `j` loop will iterate left through the sorted region,
// looking for a legal spot to insert currElement
for (var j = i - 1; j >= 0 && currElement < arr[j]; j--) {
// keep moving left while currElement is less than the j-th element
arr[j + 1] = arr[j];
// the line above will move the j-th element to the right,
// leaving a gap to potentially insert currElement
}
// insert currElement into that gap
arr[j + 1] = currElement;
}
return arr;
}
function merge(array1, array2) {
// var result as array
// while ( a and b have elements )
// if ( a[0] > b[0] )
// add b[0] to the end of result
// remove b[0] from b
// else
// add a[0] to the end of result
// remove a[0] from a
// end if
// end while
// while ( a has elements )
// add a[0] to the end of result
// remove a[0] from a
// end while
// while ( b has elements )
// add b[0] to the end of result
// remove b[0] from b
// end while
// return result
}
function mergeSort(array) {
// if ( n == 1 ) return a
// /* Split the array into two */
// var l1 as array = a[0] ... a[n/2]
// var l2 as array = a[n/2+1] ... a[n]
// l1 = mergesort( l1 )
// l2 = mergesort( l2 )
// return merge( l1, l2 )
}
function merge(array1, array2) {
let merged = [];
while (array1.length || array2.length) {
let ele1 = array1.length ? array1[0] : Infinity;
let ele2 = array2.length ? array2[0] : Infinity;
let next;
if (ele1 < ele2) {
next = array1.shift();
} else {
next = array2.shift();
}
merged.push(next);
}
return merged;
}
function mergeSort(array) {
if (array.length <= 1) {
return array;
}
let midIdx = Math.floor(array.length / 2);
let leftHalf = array.slice(0, midIdx);
let rightHalf = array.slice(midIdx);
let sortedLeft = mergeSort(leftHalf);
let sortedRight = mergeSort(rightHalf);
return merge(sortedLeft, sortedRight);
}
function quickSort(array) {
// if the length of the array is 0 or 1, return the array
// set the pivot to the first element of the array
// remove the first element of the array
// put all values less than the pivot value into an array called left
// put all values greater than the pivot value into an array called right
// call quick sort on left and assign the return value to leftSorted
// call quick sort on right and assign the return value to rightSorted
// return the concatenation of leftSorted, the pivot value, and rightSorted
}
function quickSort(array) {
if (array.length <= 1) {
return array;
}
let pivot = array.shift();
let left = array.filter((el) => el < pivot);
let right = array.filter((el) => el >= pivot);
let leftSorted = quickSort(left);
let rightSorted = quickSort(right);
return [ ...leftSorted, pivot, ...rightSorted ];
}