diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..e1eede58 Binary files /dev/null and b/.DS_Store differ diff --git a/Arrays/.DS_Store b/Arrays/.DS_Store new file mode 100644 index 00000000..f88de1fe Binary files /dev/null and b/Arrays/.DS_Store differ diff --git a/Arrays/2dArray.js b/Arrays/2dArray.js new file mode 100644 index 00000000..8642dfc8 --- /dev/null +++ b/Arrays/2dArray.js @@ -0,0 +1,31 @@ +let a = [ + [1, 2, 3], + [2, 3, 4], + [3, 4, 5] +]; + +let b = [ + [1, 2, 3], + [2, 3, 4], + [3, 4, 5] +] + +function add(a, b) { + let rows = a.length; //! find rows + let cols = a[0].length; //! find columns + let c = []; + + for(let i = 0; i < rows; i++) { + c.push(Array(cols).fill(0)); + } + + for(let i = 0; i < rows; i++) { + for(let j = 0; j < cols; j++) { + c[i][j] = a[i][j] + b[i][j]; + } +} +return c; + +} + +console.log(add(a, b)); \ No newline at end of file diff --git a/Arrays/2dConversion.js b/Arrays/2dConversion.js new file mode 100644 index 00000000..0673bb62 --- /dev/null +++ b/Arrays/2dConversion.js @@ -0,0 +1,43 @@ +//! 29/01/2022 convert 1D to 2D; + + + +let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + +let r = 2; +let c = 5; + +//! my logic +// function printMe(r, c) { +// let res = ""; +// for(let i = 0; i < r; i++) { +// for(let j = 0; j < c; j++) { +// res += arr[c*i + j] + " "; +// } +// res += "\n"; +// } +// return res; +// } + +// console.log(printMe(r, c)); + +//! sanket's logic +function convert(arr, r, c) { + let mat = []; + for(let i = 0; i < r; i++) { + mat.push(Array(c)); + } + let ptr = 0; + for(let i = 0; i < r; i++) { + for(let j = 0; j < c; j++) { + if(ptr < arr.length) { + mat[i][j] = arr[ptr++]; + } + + } + } + return mat; +} + +console.log(convert(arr, r, c)); \ No newline at end of file diff --git a/Arrays/3Sum.js b/Arrays/3Sum.js new file mode 100644 index 00000000..02db2b65 --- /dev/null +++ b/Arrays/3Sum.js @@ -0,0 +1,31 @@ +// https://leetcode.com/problems/3sum/ +var threeSum = function(nums) { + const triplets = []; + nums.sort((a, b) => a - b); + for(let i = 0; i < nums.length - 2; i++) { + if( (i > 0) && nums[i] == nums[i - 1]) { + continue; + } + let left = i + 1; + let right = nums.length - 1; + + while(left < right) { + const currentSum = nums[i] + nums[left] + nums[right]; + if(currentSum == 0) { + triplets.push([nums[i], nums[left], nums[right]]); + while(left < right && nums[left] == nums[left + 1]) left++; + while(left < right && nums[right] == nums[right - 1]) right--; + left++; + right--; + } else if(currentSum < 0) { + left++; + } else if(currentSum > 0) { + right--; + } + } + } + return triplets; +}; +const array = [-1,0,1,2,-1,-4]; + +console.log(threeSum(array)); \ No newline at end of file diff --git a/Arrays/3SumClosest.js b/Arrays/3SumClosest.js new file mode 100644 index 00000000..262fb4d4 --- /dev/null +++ b/Arrays/3SumClosest.js @@ -0,0 +1,32 @@ +// https://leetcode.com/problems/3sum-closest/ +function threeSumClosest(array, targetSum) { + + array.sort((a, b) => a - b); + console.log(array); + + let result = Infinity; + + for(let i = 0; i < array.length - 2; i++) { + + let left = i + 1; + let right = array.length - 1; + + while(left < right) { + const sum = array[left] + array[right] + array[i]; + + if(sum == targetSum) return sum; + else sum < targetSum ? left++ : right--; + + if(Math.abs(targetSum - sum) < Math.abs(targetSum - result)) + { + result = sum; + } + } + } + return result; +} + +const nums = [-1,2,1,-4]; +const target = 1; + +console.log(threeSumClosest(nums, target)); \ No newline at end of file diff --git a/Arrays/4sum.js b/Arrays/4sum.js new file mode 100644 index 00000000..97cc1a80 --- /dev/null +++ b/Arrays/4sum.js @@ -0,0 +1,40 @@ +//https://leetcode.com/problems/4sum/ +// https://www.youtube.com/watch?v=4ggF3tXIAp0 + +function fourSum(array, targetSum) { + const quadruplets = []; + array.sort((a, b) => a - b); + const len = array.length; + for(let i = 0; i < len; i++) { + for(let j = i + 1; j < len; j++) { + const currentSum = array[i] + array[j]; + const difference = targetSum - currentSum; + + let left = j + 1; + let right = array.length- 1; + + while(left < right) { + const twoSum = array[left] + array[right]; + + if(twoSum < difference) left++; + else if(twoSum > difference) right--; + else { + quadruplets[quadruplets.length] = [array[i], array[j], array[left], array[right]]; + + while(left < right && array[left] == quadruplets[quadruplets.length - 1][2]) left++; + + while(left < right && array[right] == quadruplets[quadruplets.length - 1][3]) right--; + } + } + while(j + 1 < len && array[j + 1] == array[j]) j++; + } + while(i + 1 < len && array[i + 1] == array[i]) ; + } + return quadruplets; +} + + +const nums =[1,0,-1,0,-2,2]; +const target = 0; + +console.log(fourSum(nums, target)); \ No newline at end of file diff --git a/Arrays/StriverSheet/3sum.js b/Arrays/StriverSheet/3sum.js new file mode 100644 index 00000000..806d3e5b --- /dev/null +++ b/Arrays/StriverSheet/3sum.js @@ -0,0 +1,38 @@ +//! https://leetcode.com/problems/3sum/ + +var threeSum = function(nums) { + + const triplets = []; + + nums.sort((a, b) => a - b); + + for(let i = 0; i < nums.length - 2; i++) { + + if( (i > 0) && nums[i] == nums[i - 1]) { + continue; + } + let left = i + 1; + let right = nums.length - 1; + + while(left < right) { + + const currentSum = nums[i] + nums[left] + nums[right]; + + if(currentSum == 0) { + + triplets.push([nums[i], nums[left], nums[right]]); + console.log([nums[i], nums[left], nums[right]]); + while(nums[left] == nums[left + 1]) left++; + while(nums[right] == nums[right - 1]) right--; + left++; + right--; + } else if(currentSum < 0) { + left++; + } else if(currentSum > 0) { + right--; + } + } + } + console.log(triplets); + return triplets; +}; \ No newline at end of file diff --git a/Arrays/StriverSheet/bestTimeToSellAndBuyStock.js b/Arrays/StriverSheet/bestTimeToSellAndBuyStock.js new file mode 100644 index 00000000..d0d7350b --- /dev/null +++ b/Arrays/StriverSheet/bestTimeToSellAndBuyStock.js @@ -0,0 +1,16 @@ +// https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + +// O(n) time | O(1) space +var maxProfit = function(prices) { + let maximumProfit = 0; + let minimumStockPrice = Infinity; + + for(let i = 0; i < prices.length; i++) { + const currentPrice = prices[i]; + minimumStockPrice = Math.min(minimumStockPrice, currentPrice); + maximumProfit = Math.max(maximumProfit, currentPrice - minimumStockPrice); + } + return maximumProfit; +}; + +console.log(maxProfit([7,1,5,3,6,4])); \ No newline at end of file diff --git a/Arrays/StriverSheet/buyAndSellStock.js b/Arrays/StriverSheet/buyAndSellStock.js new file mode 100644 index 00000000..650f75c8 --- /dev/null +++ b/Arrays/StriverSheet/buyAndSellStock.js @@ -0,0 +1,25 @@ +function maxProfit(prices) { + let maxProfit = 0; + let minPrice = Infinity; + for(let i = 0; i < prices.length; i++) { + const currentPrice = prices[i]; + minPrice = Math.min(minPrice, currentPrice); + maxProfit = Math.max(maxProfit, currentPrice - minPrice); + } + return maxProfit; +} + +const prices = [7,1,5,3,6,4]; + +console.log(maxProfit(prices)); + +function maxProfit(prices) { + let maxProfit = 0; + for(let i = 0; i < prices.length; i++) { + for(let j = i + 1; j < prices.length; j++) { + const profit = prices[j] - prices[i]; + maxProfit = Math.max(maxProfit, profit); + } + } + return maxProfit; + } \ No newline at end of file diff --git a/Arrays/StriverSheet/kadaneAlgorithm.js b/Arrays/StriverSheet/kadaneAlgorithm.js new file mode 100644 index 00000000..a27bd81d --- /dev/null +++ b/Arrays/StriverSheet/kadaneAlgorithm.js @@ -0,0 +1,4 @@ +// https://leetcode.com/problems/maximum-subarray/ +// https://www.algoexpert.io/questions/kadane's-algorithm + +// Refer AloExpert \ No newline at end of file diff --git a/Arrays/StriverSheet/moveZeros.js b/Arrays/StriverSheet/moveZeros.js new file mode 100644 index 00000000..ac93984d --- /dev/null +++ b/Arrays/StriverSheet/moveZeros.js @@ -0,0 +1,20 @@ +// https://leetcode.com/problems/move-zeroes/submissions/ + +function nonZeros(nums) { + + if(nums.length == 0) return; + + let currentPosition = 0; + + for(const num of nums) { + if(num != 0) nums[currentPosition++] = num; + } + + while(currentPosition < nums.length) { + nums[currentPosition++] = 0; + } + + return nums; +} + + diff --git a/Arrays/StriverSheet/nextPermutation.js b/Arrays/StriverSheet/nextPermutation.js new file mode 100644 index 00000000..1edc8111 --- /dev/null +++ b/Arrays/StriverSheet/nextPermutation.js @@ -0,0 +1,31 @@ +// https://leetcode.com/problems/next-permutation/ + + +function nextPermutation(nums) { + if(nums == null || nums.length <= 1) return nums; + + let i = nums.length - 2; + + while(i > -1 && nums[i] >= nums[i + 1]) i--; + + if(i > -1) { + let j = nums.length - 1; + while(nums[j] <= nums[i]) j--; + swap(nums, i, j); + } + + return reverse(nums, i + 1, nums.length - 1); +} + +function swap(nums, i, j) { + [ nums[i], nums[j] ] = [ nums[j], nums[i] ]; +} + +function reverse(nums, i, j) { + if(i >= j) return nums; + swap(nums, i, j); + return reverse(nums, i + 1, j - 1); + while(i < j) swap(nums, i++, j--); + return nums; +} +console.log(nextPermutation([5, 4, 3, 2, 1])); \ No newline at end of file diff --git a/Arrays/StriverSheet/pascalsTriangle.js b/Arrays/StriverSheet/pascalsTriangle.js new file mode 100644 index 00000000..93d7c965 --- /dev/null +++ b/Arrays/StriverSheet/pascalsTriangle.js @@ -0,0 +1,20 @@ +//! https://leetcode.com/problems/pascals-triangle/ + +// https://takeuforward.org/data-structure/program-to-generate-pascals-triangle/ +function generate(numRows) { + var pascal = []; + for(let i = 0; i < numRows; i++) { + pascal[i] = []; + pascal[i][0] = 1; + for(let j = 1; j < i; j++) { + pascal[i][j] = pascal[i - 1][j - 1] + pascal[i - 1][j]; + } + pascal[i][i] = 1; + } + return pascal; +} + + +const numRows = 5; + +console.log(generate(numRows)); \ No newline at end of file diff --git a/Arrays/StriverSheet/power.js b/Arrays/StriverSheet/power.js new file mode 100644 index 00000000..8d480c13 --- /dev/null +++ b/Arrays/StriverSheet/power.js @@ -0,0 +1,22 @@ +function powerHelper(a, n) { + if (n == 1) return a; + let mid = Math.floor(n / 2); + let b = powerHelper(a, mid); + let c = b * b; + console.log(c) + if (n % 2 === 0) return c; + return a * c; +} + +function power(a, n) { + let ans; + if(n < 0) { + ans = powerHelper(a, -1 * n); + ans = 1.0 / ans; + } + else { + ans = powerHelper(a, n); + } + return ans; +} +console.log(power(2.00000, -2)); diff --git a/Arrays/StriverSheet/rotateImage.js b/Arrays/StriverSheet/rotateImage.js new file mode 100644 index 00000000..cc179f3e --- /dev/null +++ b/Arrays/StriverSheet/rotateImage.js @@ -0,0 +1,32 @@ +//! https://leetcode.com/problems/rotate-image/ +//! https://www.geeksforgeeks.org/turn-an-image-by-90-degree/ + + +// O(n * m) time +function rotateImage(matrix) { + + let rotatedMatrix = matrix; + let len = matrix.length - 1; + + // for(let row = 0; row < matrix.length; row++) { + // for(let col = 0; col < matrix[0].length; col++) { + // rotatedMatrix[col][len - row] = matrix[row][col]; + // } + // } + // return rotatedMatrix; + + for(let row = 0; row < matrix.length; row++) + for(let col = row; col < matrix[row].length; col++) + [matrix[row][col], matrix[col][row] ]= [matrix[col][row], matrix[row][col]]; + + for(let row = 0; row < matrix.length; row++) + matrix[row].reverse(); + + return matrix; + +} + + +const matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];; + +console.log(rotateImage(matrix)); \ No newline at end of file diff --git a/Arrays/StriverSheet/setMatrixZeroes.js b/Arrays/StriverSheet/setMatrixZeroes.js new file mode 100644 index 00000000..088abd14 --- /dev/null +++ b/Arrays/StriverSheet/setMatrixZeroes.js @@ -0,0 +1,31 @@ +//! https://leetcode.com/problems/set-matrix-zeroes/ +//! https://takeuforward.org/data-structure/set-matrix-zero/ + +// O(n * m) time | O(1) space + +console.time("runTime"); +function setMatrixZeros(matrix) { + + let col0 = 1, rows = matrix.length, cols = matrix[0].length; + + for(let i = 0; i < rows; i++) { + if(matrix[i][0] == 0) cols = 0; + for(let j = 1; j < cols; j++) { + if(matrix[i][j] == 0) { + matrix[i][0] = matrix[0][j] = 0; + } + } + } + + for(let i = rows - 1; i > -1; i--) { + for(let j = cols - 1; j > 0; j--) { + if(matrix[i][0] == 0 || matrix[0][j] == 0) { + matrix[i][j] = 0; + } + } + if(col0 == 0) matrix[i][0] = 0; + } +} +setMatrixZeros(matrix); + +console.timeEnd("runTime") diff --git a/Arrays/StriverSheet/sortColors.js b/Arrays/StriverSheet/sortColors.js new file mode 100644 index 00000000..a627ce94 --- /dev/null +++ b/Arrays/StriverSheet/sortColors.js @@ -0,0 +1,27 @@ +// https://leetcode.com/problems/sort-colors/ + +function sortColors(nums) { + if(nums.length <= 1) return nums; + + let low = 0, mid = 0, high = nums.length - 1; + + while(mid <= high) { + const num = nums[mid]; + switch(num) { + case 0: + swap(num, low++, mid++); + break; + case 1: + mid++; + break; + case 2: + swap(num, mid, high--); + } + } + return nums; +} + +function swap(nums, i, j) { + [ nums[i], nums[j] ] = [ nums[j], nums[i] ]; +} + diff --git a/Arrays/StriverSheet/tempCodeRunnerFile.js b/Arrays/StriverSheet/tempCodeRunnerFile.js new file mode 100644 index 00000000..484673c6 --- /dev/null +++ b/Arrays/StriverSheet/tempCodeRunnerFile.js @@ -0,0 +1,2 @@ + + return a * c; \ No newline at end of file diff --git a/Arrays/androidPattern.js b/Arrays/androidPattern.js new file mode 100644 index 00000000..d6a6edbc --- /dev/null +++ b/Arrays/androidPattern.js @@ -0,0 +1,39 @@ +//! 28/01/2022 +let hoptable = []; + +function calcPattern(visited, curr, remain) { + if(remain == 0) return 1; + visited[curr] = true; + let ans = 0; + for(let i = 1; i <= 9; i++) { + if(!visited[i] && (hoptable[curr][i] == 0 || visited[hoptable[curr][i]] == true)) { + ans += calcPattern(visited, i, remain - 1); + } + } + visited[curr] = false; + return ans; + +} +function countPattern(m, n) { + for(let i = 0; i < 10; i++) { + hoptable.push(Array(10).fill(0)); + } + hoptable[1][3] = hoptable[3][1] = 2; + hoptable[1][7] = hoptable[7][1] = 4; + hoptable[3][9] = hoptable[9][3] = 6; + hoptable[7][9] = hoptable[9][7] = 8; + hoptable[1][9] = hoptable[9][1] = hoptable[3][7] = hoptable[7][3] = hoptable[2][8] = hoptable[8][2] = hoptable[4][6] = hoptable[6][4] = 5; + let ans = 0; + let visited = Array(9).fill(false); + for(let i = m; i <= n; i++) { + ans += calcPattern(visited, 1, i-1)*4; + ans += calcPattern(visited, 2, i-1)*4; + ans += calcPattern(visited, 5, i-1); + } + return ans; + +} + +console.log(countPattern(1,2)); + + diff --git a/Arrays/anotherNumberSystem.js b/Arrays/anotherNumberSystem.js new file mode 100644 index 00000000..3e43caf2 --- /dev/null +++ b/Arrays/anotherNumberSystem.js @@ -0,0 +1,62 @@ + +function alphaSystem(str) { + let len = str.length - 1; + + let result = 0; + + for(let i = 0; i < str.length; i++) { + const char = str[i]; + const val = ALPHA[char]; + + result += val * (26 ** len--); + } + + return result; +} + +const ALPHA = { + 'A': 1, + 'B': 2, + 'C': 3, + 'D': 4, + 'E': 5, + 'F': 6, + 'G': 7, + 'H': 8, + 'I': 9, + 'J': 10, + 'K': 11, + 'L': 12, + 'M': 13, + 'N': 14, + 'O': 15, + 'P': 16, + 'Q': 17, + 'R': 18, + 'S': 19, + 'T': 20, + 'U': 21, + 'V': 22, + 'W': 23, + 'X': 24, + 'Y': 25, + 'Z': 26 +} + +const str = "AA" +console.log(alphaSystem(str)); + + + +function alphaNum(str) { + let decimalNum = 0; + for(let i = 0; i < str.length; i++) { + const unitVal = Math.pow(26, str.length - i - 1); + const currentIdxVal = str[i].charCodeAt(0) - 64; + decimalNum += unitVal * currentIdxVal; + } + return decimalNum; +} + +console.log(alphaNum('ABC')); + diff --git a/Arrays/arrayOfProducts.js b/Arrays/arrayOfProducts.js new file mode 100644 index 00000000..f894f7a2 --- /dev/null +++ b/Arrays/arrayOfProducts.js @@ -0,0 +1,56 @@ +//! O(n) time | O(n) space +function arrayOfProducts(array) { + const products = new Array(array.length).fill(1); + + let leftRunningProduct = 1; + for(let i = 0; i < array.length; i++){ + products[i] = leftRunningProduct; + leftRunningProduct *= array[i]; + } + let rightRunningProduct = 1; + for(let i = array.length - 1; i > -1; i--) { + products[i] *= rightRunningProduct; + rightRunningProduct *= array[i]; + } +} + +//! O(n) time | O(n) space +function arrayOfProducts(array) { + const products = new Array(array.length).fill(1); + const leftProducts = new Array(array.length).fill(1); + const rightProducts = new Array(array.length).fill(1); + + let leftRunningProduct = 1; + for(let i = 0; i < array.length; i++) { + leftProducts[i] = leftRunningProduct; + leftRunningProduct *= array[i]; + } + let rightRunningProduct = 1; + for(let i = array.length - 1; i > -1; i--) { + rightProducts[i] = rightRunningProduct; + rightRunningProduct *= array[i]; + } + for(let i = 0; i < array.length; i++) { + products[i] = leftProducts[i] * rightProducts[i]; + } + return products; +} + +//! O(n^2) time | O(n) space +function arrayOfProducts1(array) { + const products = []; + + for(let i = 0; i { + result += (row[1] - row[0]); + }); + + return Math.round(result / matrix.length); +} + +const matrix = [ + [3, 8], + [5, 9], + [1, 5] ]; + + +console.log(avgTime(matrix)); \ No newline at end of file diff --git a/Arrays/binarySearch.cpp b/Arrays/binarySearch.cpp new file mode 100644 index 00000000..65cad586 --- /dev/null +++ b/Arrays/binarySearch.cpp @@ -0,0 +1,70 @@ +#include + +using namespace std; + + +int binarySearch(int arr[], int i, int j, int x) { + int mid; +//! USING DAC + if (i == j) { + if (arr[i] == x) { + return i; + } + else { + return -1; + } + } + else { + mid = (i + j ) / 2; + if (x == arr[mid]) { + return mid; + } + else if (x < arr[mid]) { + binarySearch(arr, i, mid - 1, x ); + } else { + binarySearch(arr, mid + 1, j, x); + } + } + + +} +//! using loop + + +int binarySearchUsingWhileLoop (int arr[], int i, int j, int x) { + int mid; + while (i < j) { + if (i == j) { + if (arr[i] == x) { + return i; + } else { + return -1; + } + } + else { + mid = (i + j) / 2; + if (x == arr[mid]) { + return mid; + } else if (x < arr[mid]) { + j = mid - 1; + } else { + i = mid + 1; + } + + } + } +} + + +int main () { + int arr[] = {1, 2, 3, 4, 5, 6, 7, 8}; + + int i = 0; + int j = sizeof(arr) / sizeof(arr[0]); + int x = 8; + + // cout << binarySearch(arr, i, j, x) << endl; + cout << binarySearchUsingWhileLoop(arr, i, j, x) << endl; + + return 0; +} \ No newline at end of file diff --git a/Arrays/classes.js b/Arrays/classes.js new file mode 100644 index 00000000..81e7be8f --- /dev/null +++ b/Arrays/classes.js @@ -0,0 +1,20 @@ +class User { + constructor(firstname = "default user", lastname = "default user", credit = NaN) { + this.firstname = firstname; + this.lastname = lastname; + this.credit = credit; + } + getFullName() { return this.firstname}; + getCredit() { return this.credit; } + editName(newName) { + const myName = newName.split(' ') + return myName; + } +} + +const user1 = new User('parma1', 'param2', 1); +const user2 = new User('param1', 'param2', 2); +const user3 = new User('param1', 'param2', 3); +const user4 = new User(); + +console.log(user4.editName("edi ted")); \ No newline at end of file diff --git a/Arrays/continousMaxSubArraySum.cpp b/Arrays/continousMaxSubArraySum.cpp new file mode 100644 index 00000000..b517f234 --- /dev/null +++ b/Arrays/continousMaxSubArraySum.cpp @@ -0,0 +1,69 @@ +#include + +using namespace std; + +int max(int leftSum, int rightSum, int crossSum) { + if (leftSum > rightSum && leftSum > crossSum) { + return leftSum; + } else if (rightSum > leftSum && rightSum > crossSum) { + return rightSum; + } + else if (crossSum > leftSum && crossSum > rightSum) { + return crossSum; + } +} + +void printArr(int arr[], int i, int j) { + for (int k = i; k <= j; k++) { + cout << arr[k] << " "; + } +} + +int findCrossSum(int arr[], int midLeft, int p, int midRight, int q) +{ + int leftBestSum = 0, leftTotalSum = 0, rightBestSum = 0, rightTotalSum = 0; + int leftBestSumPosition = -1, rightBestSumPosition = -1; + + for (int i = midLeft; i >= 0; i--) { + leftTotalSum = leftTotalSum + arr[i]; + if (leftTotalSum > leftBestSum) { + leftBestSum = leftTotalSum; + leftBestSumPosition = i; + } + } + + for (int i = midRight; i < q; i++) { + rightTotalSum = rightTotalSum + arr[i]; + if (rightTotalSum > rightBestSum) { + rightBestSum = rightTotalSum; + rightBestSumPosition = i; + } + } + printArr(arr, leftBestSumPosition, rightBestSumPosition); + +} +int continousMaxSubArraySum(int arr[], int p, int q) +{ + if ( p == q) { + return arr[p]; + } else { + int mid = (p + q) / 2; + int leftSum = continousMaxSubArraySum(arr, p, mid); + int rightSum = continousMaxSubArraySum(arr, mid + 1, q); + int crossSum = findCrossSum(arr, mid, p, mid + 1, q); + return max(leftSum, rightSum, crossSum); + } +} + +int main () { + int arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; + + int p = 0; + + int q = sizeof(arr)/sizeof(arr[0]); + + // cout << "\nMAX SUM " << continousMaxSubArraySum(arr, p, q); + continousMaxSubArraySum(arr, p, q); + + return 0; +} \ No newline at end of file diff --git a/Arrays/countingSort.js b/Arrays/countingSort.js new file mode 100644 index 00000000..bab1ecd4 --- /dev/null +++ b/Arrays/countingSort.js @@ -0,0 +1,32 @@ + function countingSort(array) { //! for only positive numbers + let outputArray = Array(array.length).fill(0); + let maxElement = Math.max(...array); //! O(n) + let n = array.length; + let frequency_array = Array(maxElement + 1).fill(0); + + //! fill the frequency array + + for(let i = 0; i < n; i++) { + + frequency_array[array[i]] += 1; + + } + //! create the prefix sum array of frequency array + for(let i = 1; i < frequency_array.length; i++) { + frequency_array[i] = frequency_array[i] + frequency_array[i - 1] ; + } + + //! fill the output array based on the correct index of last occurence of any element + + for(let i = 0; i < n; i++) { + let current_element = array[i]; + outputArray[frequency_array[current_element] - 1] = array[i]; + frequency_array[current_element] -= 1; + } + return outputArray; + } + +let array = [1, 4, 3, 2, 1, 1, 2, 3]; +let sortedArray = countingSort(array); + +console.log(sortedArray); \ No newline at end of file diff --git a/Arrays/diffPairExist.js b/Arrays/diffPairExist.js new file mode 100644 index 00000000..d6d7e96b --- /dev/null +++ b/Arrays/diffPairExist.js @@ -0,0 +1,31 @@ +function diffPair(array, k) { + let n = array.length; + let i = 1; + let j = 0; + let res = []; + + while (i < n && j < n) { + // console.log("i", i, "j",); + let diff = array[i] - array[j]; + if(diff == k) { + res.push ([array[j], array[i]]); + i++; + j++; + } else if (diff < k) { + i++; + } else if (diff > k) { + if( j + 1 != i) { + j++; + } else { + i++; + j++; + } + } + } + // return false; + return res; +} + +let array = [1, 1, 4, 6, 7, 8, 11]; + +console.log(diffPair(array, 4)); \ No newline at end of file diff --git a/Arrays/discussion_on_push.js b/Arrays/discussion_on_push.js new file mode 100644 index 00000000..c33379ae --- /dev/null +++ b/Arrays/discussion_on_push.js @@ -0,0 +1,5 @@ +let arr = [1, 2, 3, 4, 5]; + +arr.push(6); + +console.log(arr); \ No newline at end of file diff --git a/Arrays/dummy.js b/Arrays/dummy.js new file mode 100644 index 00000000..bf17ad31 --- /dev/null +++ b/Arrays/dummy.js @@ -0,0 +1,28 @@ +const quadruplets = []; + array.sort((a, b) => a - b); + const len = array.length; + for(let i = 0; i < len; i++) { + for(let j = i + 1; j < len; j++) { + const currentSum = array[i] + array[j]; + const difference = targetSum - currentSum; + + let left = j + 1; + let right = len - 1; + + while(left < right) { + const twoSum = array[left] + array[right]; + + if(twoSum < difference) left++; + if(twoSum > difference) right--; + else{ + quadruplets[quadruplets.length] = [array[i], array[j], array[left], array[right]]; + while(left < right && array[left] == quadruplets[quadruplets.length - 1][2]) left++; + while(left < right && array[right] == quadruplets[quadruplets.length - 1][3]) right--; + } + } + while(j + 1 < len && array[j + 1] == array[j]) j++; + } + while(i + 1 < len && array[i + 1] == array[i]) i++; + } + return quadruplets; + \ No newline at end of file diff --git a/Arrays/eggProblem.js b/Arrays/eggProblem.js new file mode 100644 index 00000000..c50c3b70 --- /dev/null +++ b/Arrays/eggProblem.js @@ -0,0 +1,47 @@ +function countEmptyCells(mat) { + let count = 0; + for(let i = 0; i < mat.length; i++) { + for(let j = 0; j < mat[0].length; j++) { + if(mat[i][j] === 0) count++; + else break; + } + } + return count; +} + +let mat = []; +let line = true; +while(line) { + let inp = readline(); + if(inp) { + mat.push(inp.split(',').map(item => parseInt(item))); + } else line = false; +} +console.log(countEmptyCells(mat)); + +// const mat = [ [10, 20, 30, 40], +// [15, 25, 35, 45], +// [24, 29, 37, 48], +// [32, 33, 39, 50]]; + + +// let result = []; +// for(let row = 0; row < mat[0].length; row++) { +// let sum = 0; +// for(let col = 0; col < mat.length; col++) { +// sum += mat[col][row]; +// } +// result.push(sum); +// } + +// console.log(result); + +// let result = []; +// for(let row = 0; row < mat[0].length; row++) { +// let sum = 0; +// for(let col = 0; col < mat.length; col++) { +// sum += mat[col][row]; +// } +// result.push(sum); +// } +// console.log(result); diff --git a/Arrays/findDifference.js b/Arrays/findDifference.js new file mode 100644 index 00000000..d65bcc22 --- /dev/null +++ b/Arrays/findDifference.js @@ -0,0 +1,34 @@ +// var findTheDifference = function(s, t) { + +// const obj = {}; +// for(let i = 0; i < s.length; i++) { +// if(!obj[s[i]]) obj[s[i]] = 0; +// obj[s[i]] += 1; +// } + +// let result = ""; +// for(let i = 0; i < t.length; i++) { +// if(obj[t[i]]) obj[t[i]] -= 1; +// else if(!obj[t[i]]) result += t[i] +// } +// return result; + +// let sum1 = 0; + +// for(let i = 0; i < s.length; i++) { +// sum1 += s[i].charCodeAt(); +// } +// let sum2 = 0; + +// for(let i = 0; i < t.length; i++) { +// sum2 += t[i].charCodeAt(); +// } +// return String.fromCharCode(sum2 - sum1); +// }; + +// const s = "a"; +const s = "abcde"; +// const t = "aa"; +const t = "acd"; + + diff --git a/Arrays/findIn2dArray.js b/Arrays/findIn2dArray.js new file mode 100644 index 00000000..b011b3de --- /dev/null +++ b/Arrays/findIn2dArray.js @@ -0,0 +1,45 @@ +//! 29/01/2022 +let arr = [ + [1, 2, 3, 4], + [5, 6, 7, 8], + [6, 7, 8, 9], + [7, 8, 9, 10] +]; + + function finder(row, x) { + for(let i = 3; i >= row; i--) { + if(arr[row][i] == x) { + console.log(row + 1, i + 1); + return; + } + + } + console.log("not there"); + } + +function find(x) { + let cols = arr[0].length; + if(x <= arr[0][cols - 1]) { + finder(0, x); + return; + } + if(x <= arr[1][cols - 1]) { + finder(1, x); + return; + } + if(x <= arr[2][cols - 1]) { + finder(2, x); + return; + } + if(x <= arr[3][cols - 1]) { + finder(3, x); + return; + } + console.log(-1); + +} + + +find(8.2); + + \ No newline at end of file diff --git a/Arrays/findPair.js b/Arrays/findPair.js new file mode 100644 index 00000000..7f70c62a --- /dev/null +++ b/Arrays/findPair.js @@ -0,0 +1,8 @@ +function findPair(arr, x) { + if(arr.length <= 1) return -1; + + let count = 0; + + + +} \ No newline at end of file diff --git a/Arrays/firstDuplicateValue.js b/Arrays/firstDuplicateValue.js new file mode 100644 index 00000000..2f0627bf --- /dev/null +++ b/Arrays/firstDuplicateValue.js @@ -0,0 +1,37 @@ +//? https://www.algoexpert.io/questions/First%20Duplicate%20Value +// https://leetcode.com/problems/find-the-duplicate-number/ +//! O(n) time | O(1) space +function firstDuplicateValue(array) { + for(const value of array) { + const absValue = Math.abs(value); + if(array[absValue - 1] < 0 ) return absValue; + array[absValue - 1] *= -1; + } + return - 1; +} +//! O(n) time | O(n) space +function firstDuplicateValue(array) { +const seen = new Set(); + for(const value of array) { + if(seen.has(value)) return value; + seen.add(value); + } + return -1; +} +//! O(n^2) time | O(1) space +function firstDuplicateValue(array) { +let minimumSecondIndex = array.length; + for(let i = 0; i < array.length; i++) { + const value = array[i]; + for(let j = i + 1; j < array.length; j++) { + const valueToCompare = array[j]; + if(value == valueToCompare) { + minimumSecondIndex = Math.min(minimumSecondIndex, j); + } + } + } + if(minimumSecondIndex == array.length) return -1; + + return array[minimumSecondIndex]; +} + diff --git a/Arrays/fourNumberSum.js b/Arrays/fourNumberSum.js new file mode 100644 index 00000000..cd3d264b --- /dev/null +++ b/Arrays/fourNumberSum.js @@ -0,0 +1,30 @@ +//? https://www.algoexpert.io/questions/Four%20Number%20Sum +//? Average: O(n^2) time | O(n^2) space +//? Worst: O(n^3) time | O(n^2) space + +function fourNumberSum(array, targetSum) { + const allPairSums = {}; + const quadruplets = []; + + for(let i = 1; i < array.length - 1; i++) { + for(let j = i + 1; j < array.length; j++) { + const currentSum = array[i] + array[j]; + const difference = targetSum - currentSum; + if(difference in allPairSums) { + for(const pair of allPairSums[difference]) { + quadruplets.push(pair.concat([array[i], array[j]])); + } + } + } + for(let k = 0; k < i; k++) { + const currentSum = array[i] + array[k]; + if (!(currentSum in allPairSums)) { + allPairSums[currentSum] = [[array[k], array[i]]]; + } else { + allPairSums[currentSum].push([array[k], array[i]]); + } + } + } + return quadruplets; +} +console.log(fourNumberSum([7, 6, 4, -1, 1, 2], 16)); \ No newline at end of file diff --git a/Arrays/ideaoneinput.js b/Arrays/ideaoneinput.js new file mode 100644 index 00000000..5bd6bca3 --- /dev/null +++ b/Arrays/ideaoneinput.js @@ -0,0 +1,37 @@ +process.stdin.resume(); +process.stdin.setEncoding('utf-8'); + +let inputString = ""; +let inputString1 = ""; + +let currentLine = 0; + +process.stdin.on('data', function(input) { + inputString1 += input; + +}); + +process.stdin.on('end', function(x) { + inputString1.trim(); + inputString1 = inputString1.split("\n"); + + for(let i = 0; i < inputString1.length; i++) { + inputString += inputString1[i].trim() + ' '; + } + inputString.trim(); + inputString = inputString.split(" "); + main(); +}) +function readline() { + return result = inputString[currentLine++]; +} + +function main() { + let math = parseInt(readline()); + let physics = parseInt(readline()); + let chemistry = parseInt(readline()); + + if (math < 65 || physics < 55 || chemistry < 50 || (math + physics + chemistry < 195 && math + physics < 140)) + console.log("not eligible"); + else console.log("eligible"); +} \ No newline at end of file diff --git a/Arrays/input.js b/Arrays/input.js new file mode 100644 index 00000000..a68f7d44 --- /dev/null +++ b/Arrays/input.js @@ -0,0 +1,68 @@ +/* +? process.stdin.resume(); +? process.stdin.setEncoding('utf-8'); +? +? let inputString = ""; + ! data is an event +? process.stdin.on('data', function(userInput) { +? inputString += userInput; +? console.log(inputString); +? }) +? +? process.stdin.on('end', function(x) { +? inputString.trim(); +? main(); +? }); +? +? function main() { +? +? } +? +*/ + + +process.stdin.resume(); +process.stdin.setEncoding('utf-8'); + +let inputString = ""; +let currentLine = 0; +//! data is an event +process.stdin.on('data', function(userInput) { + inputString += userInput; + // console.log(inputString); +}) + +process.stdin.on('end', function() { + inputString.trim(); + inputString = inputString.split("\n"); + main(); +}); + +function readline() { + return result = inputString[currentLine++]; //! 0++ +} + +function processArray(arr) { + let temp = arr.split(" "); + let result = []; + for(let i = 0; i < temp.length; i++) { + result.push(Number(temp[i])); + } + return result; +} + +function main() { + + let t = Number(readline()); //! here t is currentLine[0]; + + while(t > 0) { + let n = Number(readline()); + let arr = readline(); + arr = processArray(arr); + let k = Number(readline()); + console.log("length of array:", n); + console.log(typeof arr); + console.log("k is", k); + t = t - 1; + } +} \ No newline at end of file diff --git a/Arrays/intersectionOfArrays.js b/Arrays/intersectionOfArrays.js new file mode 100644 index 00000000..e69de29b diff --git a/Arrays/intersectionofLists.js b/Arrays/intersectionofLists.js new file mode 100644 index 00000000..e393c7e4 --- /dev/null +++ b/Arrays/intersectionofLists.js @@ -0,0 +1,50 @@ +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} headA + * @param {ListNode} headB + * @return {ListNode} + */ + + +function length(node) { + + let length = 0; + + while (node) { + node = node.next; + length++; + } + return length; +} +var getIntersectionNode = function(headA, headB) { + + let lengthA = length(headA); + let lengthB = length(headB); + + while (lengthA > lengthB) { + + headA = headA.next; + lengthA--; + } + + while (lengthB > lengthA) { + + headB = headB.next; + lengthB--; + } + + while (headA != headB) { + headA = headA.next; + headB = headB.next; + + } + return headA; + +}; \ No newline at end of file diff --git a/Arrays/largestRange.js b/Arrays/largestRange.js new file mode 100644 index 00000000..e537804a --- /dev/null +++ b/Arrays/largestRange.js @@ -0,0 +1,43 @@ +//? https://www.algoexpert.io/questions/Largest%20Range + +//! O(n) time | O(n) space +function largestRange(array) { + let bestRange = []; + let longestRange = 0; + const nums = {}; + + for(const num of array) { + nums[num] = true; + } + + for(const num of array) { + if(!(nums[num])) continue; + nums[num] = false; + let currentLength = 1; + let left = num - 1; + let right = num + 1; + + while(left in nums) { + nums[left] = false; + currentLength++; + left--; + } + + while(right in nums) { + nums[right] = false; + currentLength++; + right++; + } + + if(currentLength > longestRange) { + longestRange = currentLength; + bestRange = [left + 1, right - 1]; + } + } + return bestRange; +} + +// let array = [1, 11, 3, 0, 15, 5, 2, 4, 10, 7, 12, 6]; +// let array = [1, 1, 1, 3, 4]; +let array = [0, -5, 9, 19, -1, 18, 17, 2, -4, -3, 10, 3, 12, 5, 16, 4, 11, 7, -6, -7, 6, 15, 12, 12, 2, 1, 6, 13, 14, -2]; +console.log(largestRange(array)); \ No newline at end of file diff --git a/Arrays/linearSearch.cpp b/Arrays/linearSearch.cpp new file mode 100644 index 00000000..00b73b4f --- /dev/null +++ b/Arrays/linearSearch.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + + +int linearSearch(int array[], int x) { + + int len = sizeof(array) / sizeof(array[0]); + int i = 0; + + while (i < len) { + if (array[i] == x) { + return i; + } i++; + } + + return 0; + +} +int main () { + + int arr[] = {1,2,3,4,5,6,7,8}; + int x = 7; + + cout << linearSearch(arr, x) << endl; + return 0; + + +} + + + diff --git a/Arrays/longestPeak.js b/Arrays/longestPeak.js new file mode 100644 index 00000000..5d52ae8d --- /dev/null +++ b/Arrays/longestPeak.js @@ -0,0 +1,25 @@ +//? https://www.algoexpert.io/questions/Longest%20Peak +//! O(n) time | O(1) space +function longestPeak(array) { + let longestPeakLength = 0; + let i = 1; + while(i < array.length - 1) { + const isPeak = array[i - 1] < array[i] && array[ i + 1] < array[i]; + if(!isPeak) { + i++; + continue; + } + let leftIdx = i - 2; + while(leftIdx >= 0 && array[leftIdx] < array[leftIdx + 1] ) { + leftIdx--; + } + let rightIdx = i + 2; + while(rightIdx < array.length && array[rightIdx] < array[rightIdx - 1]) { + rightIdx++; + } + const currentPeakLength = rightIdx - leftIdx - 1 + longestPeakLength = Math.max(longestPeakLength, currentPeakLength); + i = rightIdx; + } + return longestPeakLength; +} diff --git a/Arrays/luckyNumber.js b/Arrays/luckyNumber.js new file mode 100644 index 00000000..fced01a7 --- /dev/null +++ b/Arrays/luckyNumber.js @@ -0,0 +1,27 @@ +// https://leetcode.com/problems/lucky-numbers-in-a-matrix/ +function luckyNumber(matrix) { + + const result = []; + + for(let row = 0; row < matrix.length; row++) { + + const min = Math.min(...matrix[row]); + + const index = matrix[row].indexOf(min); + + const colValues = []; + + for(let col = 0; col < matrix[0].length; col++) { + colValues.push(matrix[col][index]) + } + + if(min == Math.max(...colValues)) result.push(min); + } + return result; +} + +// const matrix = [[3,7,8],[9,11,13],[15,16,17]]; +const matrix = [[7, 8], [1, 2]]; + + +console.log(luckyNumber(matrix)); diff --git a/Arrays/maps.js b/Arrays/maps.js new file mode 100644 index 00000000..60f51abd --- /dev/null +++ b/Arrays/maps.js @@ -0,0 +1,30 @@ +var map = new Map(); + +map.set(0, "zero"); +map.set(01, "zero"); +map.set(02, "zero"); +map.set(03, "zero"); +map.set(04, "zero"); +map.set(05, "zero"); + + +// console.log(map); + +// for (let key of map.keys()) { +// console.log(`key is : ${key}`); +// } + +// for (let value of map.values()) { +// console.log(`value is : ${value}`); +// } + +// for (let [key, value] of map) { +// console.log(`key is : ${key}, value is : ${value}`); +// } + +// map.forEach( (key, value) => { +// console.log(value, key); +// }) + +// map.delete(2); +// console.log(map); \ No newline at end of file diff --git a/Arrays/maxSeriesOf1.js b/Arrays/maxSeriesOf1.js new file mode 100644 index 00000000..d37a4f1f --- /dev/null +++ b/Arrays/maxSeriesOf1.js @@ -0,0 +1,21 @@ +function maxSeriesOf1(array) { + let n = array.length; + let i = -1, j = 0; + let ans = 0; + while(j < n && i < n) { + if(array[j] == 1) { + ans = Math.max(ans, j - i); + j++; + } + else { + i = j; + j++; + } + } + return ans; + +} + +let array = [0, 1, 0, 0]; + +console.log(maxSeriesOf1(array)); \ No newline at end of file diff --git a/Arrays/mergeOverlappingIntervals.js b/Arrays/mergeOverlappingIntervals.js new file mode 100644 index 00000000..ad714109 --- /dev/null +++ b/Arrays/mergeOverlappingIntervals.js @@ -0,0 +1,25 @@ +//? https://www.algoexpert.io/questions/Merge%20Overlapping%20Intervals + //! O(nlogn) time | O(n) space +function mergeOverlappingIntervals(intervals) { +const sortedIntervals = intervals.sort((a, b) => a[0] - b[0]); + + const mergedIntervals = []; + let currentInterval = sortedIntervals[0]; + mergedIntervals.push(currentInterval); + + for(const nextInterval of sortedIntervals) { + const [_, currentIntervalEnd] = currentInterval; + const [nextIntervalStart, nextIntervalEnd] = nextInterval; + if(currentIntervalEnd >= nextIntervalStart) { + currentInterval[1] = Math.max(currentIntervalEnd, nextIntervalEnd); + } + else { + currentInterval = nextInterval; + mergedIntervals.push(currentInterval); + } + } + return mergedIntervals; +} + +console.log(mergeOverlappingIntervals([[1, 2], [3, 5], [4, 7], [6, 8], [9, 10]])); + diff --git a/Arrays/mergeSort.cpp b/Arrays/mergeSort.cpp new file mode 100644 index 00000000..ccaacc67 --- /dev/null +++ b/Arrays/mergeSort.cpp @@ -0,0 +1,73 @@ +#include + +using namespace std; + +void merge(int arr[], int start, int mid, int end) +{ + int leftSubArraySize = mid - start + 1; + int rightSubArraySize = end - (mid + 1) + 1; + + int leftSubArray[leftSubArraySize]; + int rightSubArray[rightSubArraySize]; + + for (int i = 0; i < leftSubArraySize; i++) + { + leftSubArray[i] = arr[i + start]; + } + for (int i = 0; i < rightSubArraySize; i++) + { + rightSubArray[i] = arr[i + mid + 1]; + } + + int i = 0; + int j = 0; + int k = start; + + while ((i < leftSubArraySize) && (j < rightSubArraySize)) + { + if (leftSubArray[i] < rightSubArray[j]) + { + arr[k++] = leftSubArray[i++]; + } + else + { + arr[k++] = rightSubArray[j++]; + } + } + while (i < leftSubArraySize) + { + arr[k++] = leftSubArray[i++]; + } + while (j < rightSubArraySize) + { + arr[k++] = rightSubArray[j++]; + } +} +int mergeSort(int arr[], int i, int j) +{ + if (i == j) + return arr[i]; + + else + { + int mid = (i + j) / 2; + mergeSort(arr, i, mid); + mergeSort(arr, mid + 1, j); + merge(arr, i, mid, j); + } +} + +int main () { + + int arr[] = {50, 60, 70, 80, 10, 12, 13, 8, 3, 2, 1, 0}; + + int len = sizeof(arr) / sizeof(arr[0]); + + mergeSort(arr, 0, 12); + + for ( int i = 0; i < 12; i++ ) { + cout << arr[i] << " "; + } + + return 0; +} \ No newline at end of file diff --git a/Arrays/minCoins.js b/Arrays/minCoins.js new file mode 100644 index 00000000..31bd6675 --- /dev/null +++ b/Arrays/minCoins.js @@ -0,0 +1,19 @@ +//! 25/01/2022 + +let n = 3; +let x = 11; +let coins = [1, 5, 7]; + +function minCoins(n) { + if(n == 0) return 0; + + let ans = Number.MAX_SAFE_INTEGER; + + for(let i = 0; i < coins.length; i++) { + if( n < coins[i]) continue; + ans = Math.min(ans, minCoins(n - coins[i])); + } + return 1 + ans; +} + +console.log(minCoins(x)); \ No newline at end of file diff --git a/Arrays/minDigit.js b/Arrays/minDigit.js new file mode 100644 index 00000000..6ca5e081 --- /dev/null +++ b/Arrays/minDigit.js @@ -0,0 +1,17 @@ +//! 24/01/2022 + +function minSteps(n) { + if(n < 10) return 1; + let str = "" + n; + let noOfDigits = str.length; + let ans = Number.MAX_SAFE_INTEGER; + for(let i = 0; i < noOfDigits; i++) { + let currDigit = str[i] - '0'; + if(currDigit == 0) continue; + ans = Math.min(ans, minSteps(n - currDigit)) + } + return 1 + ans; +} + +console.log(minSteps(27)); + diff --git a/Arrays/minRewards.js b/Arrays/minRewards.js new file mode 100644 index 00000000..3138eaa0 --- /dev/null +++ b/Arrays/minRewards.js @@ -0,0 +1,66 @@ +//! https://leetcode.com/problems/candy/ +//! O(n) time | O(n) space +function minRewards(scores) { + let rewards = scores.map(_ => 1); + console.log(rewards); + for(let i = 1; i < scores.length; i++) { + if(scores[i] > scores[i - 1]) rewards[i] = rewards[i - 1] + 1; + } + for(let i = scores.length - 2; i >= 0; i--) { + if(scores[i] > scores[i + 1]) rewards[i] = Math.max(rewards[i], rewards[i + 1] + 1); + } + return rewards.reduce((a, b) => a + b); +} + +//! O(n) time | O(n) space +// function minRewards(scores) { +// let rewards = scores.map(_ => 1); +// const locaMinIdxs = getLocalMinIdxs(scores); +// for(const localMinIdx of locaMinIdxs) { +// expandFromLocalMinIndx(localMinIdx, scores, rewards); +// } +// return rewards.reduce((a, b) => a + b); +// } + +// function getLocalMinIdxs(array) { +// if(array.length == 1) return [0]; +// let localMinIdxs = []; +// for(let i = 0; i < array.length; i++) { +// if(i == 0 && array[i] < array[i + 1]) localMinIdxs.push(i); +// if(i == array.length - 1 && array[i] < array[i - 1]) localMinIdxs.push(i); +// if(i == 0 || i == array.length - 1) continue; +// if(array[i] < array[i + 1] && array[i] < array[i - 1]) localMinIdxs.push(i); +// } +// return localMinIdxs; +// } + +// function expandFromLocalMinIndx(localMinIdx, scores, rewards) { +// let leftIdx = localMinIdx - 1; +// while(leftIdx >= 0 && scores[leftIdx] > scores[leftIdx + 1]) { +// rewards[leftIdx] = Math.max(rewards[leftIdx], rewards[leftIdx + 1] + 1); +// leftIdx--; +// } +// let rightIdx = localMinIdx + 1; +// while(rightIdx < scores.length && scores[rightIdx] > scores[rightIdx - 1]) { +// rewards[rightIdx] = rewards[rightIdx - 1] + 1; +// rightIdx++; +// } +// } + +//! O(n^2) time | O(n) space +// function minRewards(scores) { +// let rewards = scores.map(_ => 1); +// for(let i = 1; i < scores.length; i++) { +// let j = i - 1; +// if(scores[i] > scores[j]) { +// rewards[i] = rewards[j] + 1; +// } else { +// while(j >= 0 && scores[j] > scores[j + 1]) { +// rewards[j] = Math.max(rewards[j], rewards[j + 1] + 1); +// j--; +// } +// } +// } return rewards.reduce((a, b) => a + b); +// } + +console.log(minRewards([8, 4, 2, 1, 3, 6, 7, 9, 5])); \ No newline at end of file diff --git a/Arrays/missingNumber.js b/Arrays/missingNumber.js new file mode 100644 index 00000000..8efdec07 --- /dev/null +++ b/Arrays/missingNumber.js @@ -0,0 +1,21 @@ +function findMissingNumber(array) { + array.sort((a, b) => a - b) + + for(let i = 0; i < array.length - 1; i++) { + const j = i + 1; + if(array[j] - array[i] != 1) { + return array[i] + 1; + } + } +} + +function getMissing(array, n = array.length) { + let total = Math.floor( (n + 1) * (n + 2) / 2); + for(let i = 0; i < array.length; i++) { + total -= array[i]; + } + return total +} + +const array = [1, 2, 5, 6, 7, 8, 3]; +console.log(getMissing(array)); \ No newline at end of file diff --git a/Arrays/monotonicArray.js b/Arrays/monotonicArray.js new file mode 100644 index 00000000..b995066c --- /dev/null +++ b/Arrays/monotonicArray.js @@ -0,0 +1,22 @@ + +//! O(n) time | O(1) space +function isMonotonic(array) { +if(array.length <= 2) return true; +let direction = array[1] - array[0]; +for(let i = 2; i < array.length; i++) { + if(direction == 0) { + direction = array[i] - array[i - 1]; + continue; + } + if(breaksDirection(direction, array[i - 1], array[i])) { + return false; + } + } + return true; +} + +function breaksDirection(direction, previousInt, currentInt) { + const difference = currentInt - previousInt; + if(direction > 0) return difference < 0; + return difference > 0; +} \ No newline at end of file diff --git a/Arrays/moveElementToEnd.js b/Arrays/moveElementToEnd.js new file mode 100644 index 00000000..7ca4dfae --- /dev/null +++ b/Arrays/moveElementToEnd.js @@ -0,0 +1,12 @@ +//? https://www.algoexpert.io/questions/Move%20Element%20To%20End +//! O(n) time | O(1) space +function moveElementToEnd(array, toMove) { +let i = 0; +let j = array.length - 1; +while(i < j) { + while( i < j && array[j] == toMove) j--; + if(array[j] == toMove) [ array[i], array[j] ] = [ array[j], array[i] ]; + i++; + } return array; +} + diff --git a/Arrays/narcissistic.js b/Arrays/narcissistic.js new file mode 100644 index 00000000..dfc675d5 --- /dev/null +++ b/Arrays/narcissistic.js @@ -0,0 +1,20 @@ +//! https://relevel.com/courses/backend-development-course-0001/schedule/class-details/ae173dd6-a086-4a56-85d0-0e41f00cdf14/live-class + +let num = 10000; + +for (let n = 0; n <= num; n++) { + + let str = "" + n; + let numberOfDigits = str.length; + let temp = n; + let sum = 0; + + while (temp > 0) { + let lastDigit = temp % 10; + sum = sum + Math.pow(lastDigit, numberOfDigits); + temp = Math.floor(temp / 10); + } + if (sum == n) { + console.log(n); + } +} \ No newline at end of file diff --git a/Arrays/nonConstructibleChange.js b/Arrays/nonConstructibleChange.js new file mode 100644 index 00000000..ff6a73be --- /dev/null +++ b/Arrays/nonConstructibleChange.js @@ -0,0 +1,19 @@ +//? https://www.algoexpert.io/questions/Non-Constructible%20Change +let coins = [5, 7, 1, 1, 2, 3, 22]; + +//! O(nlogn) | space O(1) + +function findCoin(coins) { + coins.sort((a, b) => a - b); + + const currentChangeCreated = 0; + for(const coin in coins) { + if(coin > currentChangeCreated + 1) return currentChangeCreated + 1; + + currentChangeCreated += coins; + } +} + + + +console.log(findCoin(coins)); \ No newline at end of file diff --git a/Arrays/numberOfInversions.cpp b/Arrays/numberOfInversions.cpp new file mode 100644 index 00000000..c50783d0 --- /dev/null +++ b/Arrays/numberOfInversions.cpp @@ -0,0 +1,69 @@ +#include "bits/stdc++.h" +using namespace std; + +int merge(int arr[], int start, int mid, int end) +{ + int inversions = 0; + int l = 0; + int len = sizeof(arr) / sizeof(arr[0]); + + int leftSubArraySize = mid - start + 1; + int rightSubArraySize = end - mid; + + int leftSubArray[leftSubArraySize]; + int rightSubArray[rightSubArraySize]; + + for (int i = 0; i < leftSubArraySize; i++) + { + leftSubArray[i] = arr[i + start + i]; + } + for (int i = 0; i < rightSubArraySize; i++) + { + rightSubArray[i] = arr[i + mid + i]; + } + + int i = 0; + int j = 0; + int k = start; + // int b[len]; + + while ((i < leftSubArraySize) && (j < rightSubArraySize)) + { + if (leftSubArray[i] < rightSubArray[j]) + { + arr[k++] = leftSubArray[i++]; + } + else + { + arr[k++] = rightSubArray[j++]; + inversions += leftSubArraySize - i; + } + } + + while (i < leftSubArraySize) + { + arr[k++] = leftSubArray[i++]; + } + while (j < rightSubArraySize) + { + arr[k++] = rightSubArray[j++]; + } + return inversions; +} +int mergeSort(int arr[], int i, int j) +{ + if (i == j) return 0; + int mid = (i + j) / 2; + int leftInversions = mergeSort(arr, i, mid); + int rightInversions = mergeSort(arr, mid + 1, j); + int mergedInversions = merge(arr, i, mid, j); + + return leftInversions + rightInversions + mergedInversions; +} +int main() +{ + + int arr[] ={50, 40, 20, 5, 19, 90, 23, 16}; + cout << mergeSort(arr, 0, 8); + return 0; +} diff --git a/Arrays/palindrome.js b/Arrays/palindrome.js new file mode 100644 index 00000000..8642e7da --- /dev/null +++ b/Arrays/palindrome.js @@ -0,0 +1,16 @@ +//! 24/01/2022 + +function checkPalindrome(str, i, j) { + if(str[i] == str[j]) { + console.log(str[i],'--', str[j]); + if(i == j || i + 1 == j) return true; + return checkPalindrome(str, i+1, j-1); + } + return false; +} + +let str = 'ABBBBBBAABBBBBBA'; +let i = 0; +let j = str.length - 1 ; + +console.log(checkPalindrome(str, i, j)); \ No newline at end of file diff --git a/Arrays/permutations.js b/Arrays/permutations.js new file mode 100644 index 00000000..3c5c9400 --- /dev/null +++ b/Arrays/permutations.js @@ -0,0 +1,26 @@ +function f(str, i) { + if(i == str.length - 1) { + console.log(str); + return; + } + let arr = Array(26).fill(false); + for(let j = i; j < str.length; j++) { + let current_char = str[j]; + + if(arr[current_char.charCodeAt(0) - 97] == false) { + arr[current_char.charCodeAt(0) - 97] = true; + swap(str, i, j); + f(str, i+1); + swap(str, i, j); + } + } +} + +function swap(str, m, n) { + let temp = str[m]; + str[m] = str[n]; + str[n] = temp; +} +let arr = ['a', 'b', 'a']; + +f(arr, 0); \ No newline at end of file diff --git a/Arrays/platfromJump.js b/Arrays/platfromJump.js new file mode 100644 index 00000000..628802b2 --- /dev/null +++ b/Arrays/platfromJump.js @@ -0,0 +1,22 @@ +//! 24/01/2022 + +function platformJump(n, k) { + if(n == 0) return 0; + if(n == 1) return Math.abs(arr[1] - arr[0]); + + let ans = Number.MAX_SAFE_INTEGER; + for(var i = 1; i <= k; i++) { + if((n - i) >= 0) { + ans = Math.min(ans, platformJump(n-i, k) + Math.abs(arr[n] - arr[n - i])); + } + } + return ans; +} + + +// let arr = [1, 3, 4, 5, 2]; +let arr = [40, 10, 20, 70, 80, 10, 20, 70, 80, 60]; +let k = 4; + +console.log(platformJump(arr.length-1, k)); +console.log(Number.MAX_SAFE_INTEGER); diff --git a/Arrays/printBinaryWithoutConsecutive1.js.js b/Arrays/printBinaryWithoutConsecutive1.js.js new file mode 100644 index 00000000..a2023569 --- /dev/null +++ b/Arrays/printBinaryWithoutConsecutive1.js.js @@ -0,0 +1,19 @@ +function f(n, i, str) { + if(i == n) { + console.log(str); + return; + } + if(i > n) return; + if(str[str.length - 1] == '0') { + f(n, i + 1, str + '0'); + f(n, i + 1, str + '1'); + } else if(str[str.length - 1] == '1') { + // f(n, i + 2, str + '01'); + f(n, i + 1, str + '0'); + } +} + +let n = 4; + +f(n, 1, "0"); +f(n, 1, "1"); \ No newline at end of file diff --git a/Arrays/printWaveForm.js b/Arrays/printWaveForm.js new file mode 100644 index 00000000..61d0c274 --- /dev/null +++ b/Arrays/printWaveForm.js @@ -0,0 +1,28 @@ +let a = [ [1, 2, 3, 4], + [2, 3, 4, 5], + [3, 4, 5, 6], + [40, 50, 60, 70]]; + + + +function wavePrint(arr) { + let n = arr.length; + let m = arr[0].length; + let result = ""; + for(let col = 0; col < m; col++) { + if(col % 2 == 0) { + //! even column + for(let row = 0; row < n; row++) { + result += arr[row][col] + " "; + } + } else { + //! odd column + for(let row = n - 1; row >= 0; row--) { + result += arr[row][col] + " "; + } + } + } + return result; +} + +console.log(wavePrint(a)); \ No newline at end of file diff --git a/Arrays/quickSort.cpp b/Arrays/quickSort.cpp new file mode 100644 index 00000000..bd077ce6 --- /dev/null +++ b/Arrays/quickSort.cpp @@ -0,0 +1,66 @@ +#include +using namespace std; + +void printArr(int arr[], int len) { + for (int i = 0; i < len; i++) { + cout << arr[i] << " "; + } +} + +void swap(int *i, int *j) { + int temp = *i; + *i = *j; + *j = temp; +} + +int partition(int arr[], int p, int q) { + int i = p; + int x = arr[i]; // ! PIVOT + + for (int j = p + 1; j <= q; j++) { + if (arr[j] <= x) { + i++; + swap(&arr[i], &arr[j]); + } + } + swap(&arr[i], &arr[p]); + return i; +} + +int quickSort(int arr[], int p, int q) { + // if (p >= q) return; + // else { + // int m = partition(arr, p, q); + // quickSort(arr, p, m - 1); + // quickSort(arr, m + 1, q); + // } + + //! MODIFIED QUICK SORT + + while (p <= q) { + if (p == q) return arr[p]; + else { + int m = partition(arr, p, q); + if ( (m - p) < (q - m) ) { + quickSort(arr, p, m - 1); + p = m + 1; + } else { + quickSort(arr, m + 1, q); + q = m - 1; + } + } + } +} + +int main () { + + int arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + + int len = sizeof(arr)/ sizeof(arr[0]); + + quickSort(arr, 0, len - 1); + + printArr(arr, len); + + return 0; +} \ No newline at end of file diff --git a/Arrays/reduceArray.js b/Arrays/reduceArray.js new file mode 100644 index 00000000..836fdd9b --- /dev/null +++ b/Arrays/reduceArray.js @@ -0,0 +1,27 @@ +function reduceArray(array) { + + const count = {}; + const result = []; + + for(let i = 0; i < array.length; i++) { + if(!(array[i] in count)) { + count[array[i]] = 1; + } else { + count[array[i]] += 1; + } + } + for(const num in count) { + if(count[num] == 1) { + result.push(parseInt(num)) + } + if(count[num] >= 2) { + result.push(parseInt(num)) + result.push(parseInt(num)) + } + } + return result; +} + +const array = [1, 2, 2, 3, 3, 3, 4, 4 ,6]; + +console.log(reduceArray(array)); \ No newline at end of file diff --git a/Arrays/reverseVowels.js b/Arrays/reverseVowels.js new file mode 100644 index 00000000..1b5df93a --- /dev/null +++ b/Arrays/reverseVowels.js @@ -0,0 +1,34 @@ +var reverseVowels = function(s) { + + let vowelCount = []; + + for(let i = 0; i < s.length; i++) { + const letter = s[i]; + if(letter in VOWELS) vowelCount.push(letter); + } + let k = vowelCount.length - 1; + let str = s.split(''); + for(let i = 0; i < s.length; i++) { + const letter = s[i]; + if(letter in VOWELS){ + str[i] = vowelCount[k--]; + } + } + return str.join(''); +}; + +const VOWELS = { + 'a': true, + 'e': true, + 'i': true, + 'o': true, + 'u': true, + 'A': true, + 'E': true, + 'I': true, + 'O': true, + 'U': true, +} + + +console.log(reverseVowels("aA")); \ No newline at end of file diff --git a/Arrays/selectionProcedure.cpp b/Arrays/selectionProcedure.cpp new file mode 100644 index 00000000..0c8d8d3e --- /dev/null +++ b/Arrays/selectionProcedure.cpp @@ -0,0 +1,54 @@ +#include + +using namespace std; + +void swap(int *i, int *j) +{ + int temp = *i; + *i = *j; + *j = temp; +} +int partition(int arr[], int p, int q) +{ + int i = p; + int x = arr[i]; // ! PIVOT + + for (int j = p + 1; j <= q; j++) + { + if (arr[j] <= x) + { + i++; + swap(&arr[i], &arr[j]); + } + } + swap(&arr[i], &arr[p]); + return i; +} +int selectionProcedure(int arr[], int p, int q, int k) { + if (p == q) return arr[p]; + else + { + int m = partition(arr, p, q); + if (m == k) return arr[k]; + else { + if (k < m) + selectionProcedure(arr, p, m - 1, q); + else + { + selectionProcedure(arr, m + 1, q, k); + } + } + } +} + +int main () { + + int arr[] = { 50, 25, 85, 45, 30, 62, 88, 98, 110, 15, 29, 69 }; + + int q = sizeof(arr) / sizeof(arr[0]); + int p = 0; + int k = 4; + cout << selectionProcedure(arr, p, q, k); + + return 0; +} \ No newline at end of file diff --git a/Arrays/shoePair.js b/Arrays/shoePair.js new file mode 100644 index 00000000..a3a52058 --- /dev/null +++ b/Arrays/shoePair.js @@ -0,0 +1,23 @@ + + +function shoePair(arr) { + + let set = new Set(); + + for(let i = 0; i < arr.length; i++) { + for(let j = 0; j < arr[i].length; j++) { + set.add(arr[i][j]); + } + } + + let result = []; + + for (const item of set.values()) { + let temp = [item, item]; + result.push(temp); + } + return result; +} +const matrix = [[3,3,8],[9,8,9],[15,15]]; + +console.log(shoePair(matrix)); \ No newline at end of file diff --git a/Arrays/simplifyPath.js b/Arrays/simplifyPath.js new file mode 100644 index 00000000..6b64afa1 --- /dev/null +++ b/Arrays/simplifyPath.js @@ -0,0 +1,27 @@ + +// https://leetcode.com/problems/simplify-path/ +var simplifyPath = function(path) { + + let startingWithSlash = path[0] === '/'; + let tokens = path.split('/').filter(isImportantToken); + let stack = []; + + if(startingWithSlash) stack.push(''); + + for(const token of tokens) { + if(token === '..') { + if(stack.length == 0 || stack[stack.length - 1] === '..') + stack.push(token); + else if(stack[stack.length - 1] !== '') + stack.pop(); + } else { + stack.push(token); + } + } + if(stack.length === 1 && stack[stack.length - 1] === '') return '/'; + return stack.join('/'); +}; + +function isImportantToken(token) { + return token.length > 0 && token !== '.'; +} \ No newline at end of file diff --git a/Arrays/smallestDifference.js b/Arrays/smallestDifference.js new file mode 100644 index 00000000..39141aee --- /dev/null +++ b/Arrays/smallestDifference.js @@ -0,0 +1,26 @@ +//? https://www.algoexpert.io/questions/Smallest%20Difference +//! O(nlog(n) + mlog(m)) time | O(1) space +function smallestDifference(arrayOne, arrayTwo) { +arrayOne.sort((a, b) => a - b); +arrayTwo.sort((a, b) => a - b); +let idxOne = 0; +let idxTwo = 0; +let smallest = Infinity; +let current = Infinity; +let smallestPair = []; +while(idxOne < arrayOne.length && idxTwo < arrayTwo.length) { + let firstNum = arrayOne[idxOne]; + let secondNum = arrayTwo[idxTwo]; + if(firstNum < secondNum) { + current = secondNum - firstNum; + idxOne++; + } else if(secondNum < firstNum) { + current = firstNum - secondNum; + idxTwo++; + } else return [firstNum, secondNum]; + if(smallest > current) { + smallest = current; + smallestPair = [firstNum, secondNum]; + } +} return smallestPair; +} \ No newline at end of file diff --git a/Arrays/somefile.txt b/Arrays/somefile.txt new file mode 100644 index 00000000..e69de29b diff --git a/Arrays/sort012.js b/Arrays/sort012.js new file mode 100644 index 00000000..66846899 --- /dev/null +++ b/Arrays/sort012.js @@ -0,0 +1,25 @@ +function sortZeroOneTwo(array) { + + const counts = {0: 0, 1:0, 2:0}; + + for (let i = 0; i < array.length; i++) { + counts[array[i]] += 1; + } + let len = 0; + + for(const count in counts) { + let numCount = counts[count]; + + while(numCount >= 1) { + array[len++] = parseInt(count); + numCount--; + } + } + return array; + +} + +const array = [1, 1, 1, 2, 0, 0, 0]; + + +console.log(sortZeroOneTwo(array)); \ No newline at end of file diff --git a/Arrays/sortStudents.js b/Arrays/sortStudents.js new file mode 100644 index 00000000..9ce32e42 --- /dev/null +++ b/Arrays/sortStudents.js @@ -0,0 +1,26 @@ +function ordering(arr, m, n) { + + let result = [...Array(m)].map(e => Array(n)); + + let newArr = []; + + for(let i = 0; i < m; i++) { + for(let j = 0; j < n; j++) { + newArr.push(arr[i][j]); + } + } + newArr.sort((a, b) => a - b); + + let k = 0; + for(let i = 0; i < m; i++) { + for(let j = 0; j < n; j++) { + result[i][j] = newArr[k]; + k++; + } + } + return result; + +} + +const arr = [[3, 8, 7], [16, 15, 7], [11, 9, 6]]; +console.log(ordering(arr, 3, 3)); \ No newline at end of file diff --git a/Arrays/sortedSquareArray.js b/Arrays/sortedSquareArray.js new file mode 100644 index 00000000..947f1bf9 --- /dev/null +++ b/Arrays/sortedSquareArray.js @@ -0,0 +1,2 @@ +let array = [-7, -5, -4, 3, 6, 8, 9]; + diff --git a/Arrays/sortedSquaredArray.js b/Arrays/sortedSquaredArray.js new file mode 100644 index 00000000..70eff926 --- /dev/null +++ b/Arrays/sortedSquaredArray.js @@ -0,0 +1,31 @@ +//! https://www.algoexpert.io/questions/Sorted%20Squared%20Array +//! O(nlogn) time | O(n) space +function sortedSquaredArray(array) { + const sortedSquares = new Array(array.length).fill(0); + const smallerValueIdx = 0; + const largerValueIdx = array.length - 1; + for(let idx = array.length - 1; idx >= 0; idx--) { + const smallerValue = array[smallerValueIdx]; + const largerValue = array[largerValueIdx]; + if(Math.abs(smallerValue) > Math.abs(largerValue)) { + sortedSquares[idx] = smallerValue * smallerValue; + smallerValueIdx++; + } else { + sortedSquares[idx] = largerValue * largerValue; + largerValueIdx--; + } + } + return sortedSquares; +} + + +//! O(n) time | O(n) space +function sortedSquaredArray(array) { + const sortedSquares = new Array(array.length).fill(0); + for(let idx =0; idx < array.length; idx++) { + const value = array[idx]; + sortedSquares[idx] = value * value; + } + sortedSquares.sort((a, b) => a - b); + return sortedSquares; +} diff --git a/Arrays/specialPositions.js b/Arrays/specialPositions.js new file mode 100644 index 00000000..0749f91f --- /dev/null +++ b/Arrays/specialPositions.js @@ -0,0 +1,45 @@ +// https://leetcode.com/problems/special-positions-in-a-binary-matrix/ + +var numSpecial = function(mat) { + + const rowSum = []; + const colSum = []; + + // sum of all rows + for(let i = 0; i < mat.length; i++) { + rowSum[i] = 0; + for(j = 0; j < mat[0].length; j++) { + rowSum[i] += mat[i][j]; + } + } + // Sum of all cols + for(let i = 0; i < mat[0].length; i++) { + + colSum[i] = 0; + for(let j = 0; j < mat.length; j++) { + colSum[i] += mat[j][i]; + } + } + let count = 0; + for(let i = 0; i < mat.length; i++) { + for(let j = 0; j < mat[0].length; j++) { + if(mat[i][j] == 1 && rowSum[i] == 1 && colSum[j] == 1) { + count += 1; + + } + } + } +return count; +}; + +// const matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1] ]; +// const matrix = [[0,0,0,0,0,1,0,0], +// [0,0,0,0,1,0,0,1], +// [0,0,0,0,1,0,0,0], +// [1,0,0,0,1,0,0,0], +// [0,0,1,1,0,0,0,0]]; +// const matrix = [[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,1,0,0]]; +const matrix = [[1,0,0],[0,0,1],[1,0,0]]; + + +console.log(numSpecial(matrix)); \ No newline at end of file diff --git a/Arrays/spiralTraverse.cpp b/Arrays/spiralTraverse.cpp new file mode 100644 index 00000000..ec5d7325 --- /dev/null +++ b/Arrays/spiralTraverse.cpp @@ -0,0 +1,72 @@ +#include +using namespace std; + + //! using loops O(n) time | O(n) space +vector spiralTraverse(vector> array) { + + + vector result = {}; + int startRow = 0, endRow = array.size() - 1; + int startCol = 0, endCol = array[0].size() - 1; + + while ((startRow <= endRow) && (startCol <= endCol)) { + + for (int col = startCol; col <= endCol; col++) { + result.push_back(array[startRow][col]); + } + for (int row = startRow + 1; row <= endRow; row++) { + result.push_back(array[row][endCol]); + } + for (int col = endCol - 1; col >= startCol; col--) { + result.push_back(array[endRow][col]); + } + for(int row = endRow + 1; row < startRow; row++) { + result.push_back(array[row][startCol]); + } + startRow++; + endRow--; + startCol++; + endCol-- + } + + return result; + + +} + +//! Using Recursion + + +int spiralTraverse(int array[][]) { + vector result = {}; + spiralFill(array, 0, array.size() - 1, 0, array[0].size() - 1, result); + return result; + +} + +spiralFill(int array[][], int startRow, int endRow, int startCol, endCol, vector result = {}) { + + if (startRow > endRow || startCol > endCol) { + return; + } + + for (int col = startCol; col <= endCol; col++) + { + result.push_back(array[startRow][col]); + } + for (int row = startRow + 1; row <= endRow; row++) + { + result.push_back(array[row][endCol]); + } + for (int col = endCol - 1; col >= startCol; col--) + { + result.push_back(array[endRow][col]); + } + for (int row = endRow + 1; row < startRow; row++) + { + result.push_back(array[row][startCol]); + } + spiralFill(int array[][], int startRow + 1, int endRow -1, int startCol + 1, endCol - 1, vector result = {}) +} + + diff --git a/Arrays/spiralTraverse.js b/Arrays/spiralTraverse.js new file mode 100644 index 00000000..bf10fe5b --- /dev/null +++ b/Arrays/spiralTraverse.js @@ -0,0 +1,61 @@ +//? https://www.algoexpert.io/questions/Spiral%20Traverse +//! O(n) time | O(n) space +function spiralTraverse(array) { + const result = []; + let startRow = 0, + endRow = array.length - 1; + let startCol = 0, + endCol = array[0].length - 1; + + while(startRow <= endRow && startCol <= endCol) { + for(let col = startCol; col <= endCol; col++) { + result.push(array[startRow][col]); + } + for(let row = startRow + 1; row <= endRow; row++) { + result.push(array[row][endCol]); + } + for(let col = endCol - 1; col >= startCol; col--) { + /** + * Handle the edge case when there's a single row + * in the middle of the matrix. In this case, we don't + * want to double-count the values in this row, which + * we've already counted in the first for loop above. + */ + if(startRow == endRow) break; + result.push(array[endRow][col]); + } + for(let row = endRow - 1; row > startRow; row--) { + /** + * Handle the edge case when there's a single column + * in the middle of the matrix. In this case, we don't + * want to double-count the values in this column, which + * we've already counted in the second for loop above. + */ + if(startCol == endCol) break; + result.push(array[row][startCol]); + } + startRow++; + endRow--; + startCol++; + endCol--; + + } return result; +} + +const array = [ +//! [1, 2, 3, 4], +//! Test case for line no. 18 [10, 11, 12, 5], +//! startRow === endRow [9, 8, 7, 6] + +//! [1, 2, 3], +//! [12, 13, 4], +//! Test case for line no. 23 11, 14, 5], +//! startCol === endCol [10, 15, 6], +//! [9, 8, 7] + +] + +console.log(spiralTraverse(array)); + + + diff --git a/Arrays/straightMaxMin.cpp b/Arrays/straightMaxMin.cpp new file mode 100644 index 00000000..7484c739 --- /dev/null +++ b/Arrays/straightMaxMin.cpp @@ -0,0 +1,124 @@ +// TODO WITHOUT DAC O(n) EVERY CASE | O(n) space + + +#include +using namespace std; + +// int findMaxMinWithoutDAC () { +// int array[] = {50, 70, 60, 35, 25, 75, 12}; +// int max = array[0]; +// int min = array[0]; + +// int sizeOfArray = sizeof(array) / sizeof(array[0]); + +// cout << "Array Size: " << sizeOfArray << endl; + +// for (int i = 1; i < sizeOfArray - 1; i++) +// { +// if (max < array[i]) +// { +// max = array[i]; +// } +// else if (min > array[i]) +// { +// min = array[i]; +// } +// } + +// cout << "max: " << max << " min: " << min << endl; +// return 0; +// } + +// int main() +// { +// int array[] = {50, 70, 60, 35, 25, 75, 12}; +// int firstIndex = 0; +// int lastIndex = sizeof(array) / sizeof(array[0]); + +// findMaxMinWithDAC(array, firstIndex, lastIndex); + +// return 0; +// } + +// TODO WITH DAC O(n) EVERY CASE | O(n) space + + +#include +using namespace std; + +// structure is used to return +// two values from minMax() +struct Pair +{ + int min; + int max; +}; + +struct Pair getMinMax(int arr[], int low, int high) +{ + struct Pair minmax, mml, mmr; + int mid; + + // If there is only one element + if (low == high) + { + minmax.max = arr[low]; + minmax.min = arr[low]; + return minmax; + } + + // If there are two elements + if (high == low + 1) + { + if (arr[low] > arr[high]) + { + minmax.max = arr[low]; + minmax.min = arr[high]; + } + else + { + minmax.max = arr[high]; + minmax.min = arr[low]; + } + return minmax; + } +else { + + // If there are more than 2 elements + mid = (low + high) / 2; + mml = getMinMax(arr, low, mid); + mmr = getMinMax(arr, mid + 1, high); + + // Compare minimums of two parts + if (mml.min < mmr.min) + minmax.min = mml.min; + else + minmax.min = mmr.min; + + // Compare maximums of two parts + if (mml.max > mmr.max) + minmax.max = mml.max; + else + minmax.max = mmr.max; + + return minmax; +} +} + +// Driver code +int main() +{ + int arr[] = {1000, 11, 445, + 1, 330, 3000}; + int arrSize = 6; + + struct Pair minmax = getMinMax(arr, 0, arrSize - 1); + + cout << "Minimum element is " << minmax.min << endl; + + cout << "Maximum element is " << minmax.max; + + return 0; +} + + \ No newline at end of file diff --git a/Arrays/stringStrength.js b/Arrays/stringStrength.js new file mode 100644 index 00000000..fd703c2a --- /dev/null +++ b/Arrays/stringStrength.js @@ -0,0 +1,22 @@ +function stringStrength(str) { + let longest = [0, 1]; + let startIdx = 0; + let lastSeen = {}; + + for(let i = 0; i < str.length; i++) { + const char = str.charAt(i); + if(char in lastSeen) { + startIdx = Math.max(startIdx, lastSeen[char] + 1); + } + if(longest[1] - longest[0] < i + 1 - startIdx) { + longest = [startIdx, i + 1]; + } + lastSeen[char] = i; + } + + const longestStringLength = str.slice(longest[0], longest[1]).length; + + return ((longestStringLength / str.length) * 100).toFixed(2); +} + +console.log(stringStrength("cccc")); \ No newline at end of file diff --git a/Arrays/subarraySort.js b/Arrays/subarraySort.js new file mode 100644 index 00000000..bfb7fc0d --- /dev/null +++ b/Arrays/subarraySort.js @@ -0,0 +1,32 @@ +//? https://www.algoexpert.io/questions/Subarray%20Sort +function subarraySort(array) { + let minOutOfOrder = Infinity; + let maxOutOfOrder = -Infinity; + for(let i = 0; i < array.length; i++) { + const num = array[i]; + if(isOutOfOrder(i, num, array)) { + minOutOfOrder = Math.min(minOutOfOrder, num); + maxOutOfOrder = Math.max(maxOutOfOrder, num); + } + } + if(minOutOfOrder == Infinity) return [-1, -1]; + + let subArrayLeftIdx = 0; + while(minOutOfOrder >= array[subArrayLeftIdx]) { + subArrayLeftIdx++; + } + let subArrayRightIdx = array.length - 1; + while(maxOutOfOrder <= array[subArrayRightIdx]) { + subArrayRightIdx--; + } + return [subArrayLeftIdx, subArrayRightIdx]; +} +function isOutOfOrder(i, num, array) { + if(i == 0) return num > array[i + 1]; + if(i == array.length - 1) return num < array[i - 1]; + return num > array[i + 1] || num < array[i - 1]; +} + +console.log(subarraySort([1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19])); + + diff --git a/Arrays/subsequence.js b/Arrays/subsequence.js new file mode 100644 index 00000000..179183c1 --- /dev/null +++ b/Arrays/subsequence.js @@ -0,0 +1,15 @@ +// ! 25/01/2022 + +function f(str, output) { + if(str == "") { + console.log(output); + return; + } + let ch = str[0]; // ! a + let restOfTheString = str.substring(1); // ! bc + // console.log("restOfTheString",restOfTheString); + f(restOfTheString, output + ch); + f(restOfTheString, output); +} + +f("abc", ""); \ No newline at end of file diff --git a/Arrays/sudoku.js b/Arrays/sudoku.js new file mode 100644 index 00000000..54655fc1 --- /dev/null +++ b/Arrays/sudoku.js @@ -0,0 +1,78 @@ +//! 28/01/2022 + +let grid = [ + [5,3,0,0,7,0,0,0,0], + [6,0,0,1,9,5,0,0,0], + [0,9,8,0,0,0,0,6,0], + [8,0,0,0,6,0,0,0,3], + [4,0,0,8,0,3,0,0,1], + [7,0,0,0,2,0,0,0,6], + [0,6,0,0,0,0,2,8,0], + [0,0,0,4,1,9,0,0,5], + [0,0,0,0,8,0,0,7,9] +]; +function display(grid) { + let result = "__ \n" + for(let i = 0; i < 9; i++) { + for(let j = 0; j < 9; j++) { + result += grid[i][j] + " | "; + } + result += "\n"; + } + console.log(result); +} + +function isSafe(i, j, num) { //! for the ith row, go to all possible columns. + for(let c = 0; c < 9; c++) { + if(grid[i][c] == num) return false; + } + for(let r = 0; r < 9; r++) { + if(grid[r][j] == num) return false; + } + let sr = (Math.floor(i/3))*3; + let sc = (Math.floor(j/3))*3; + for(let x = 0; x < 3; x++) { + for(let y = 0; y < 3; y++) { + if(grid[sr + x][sc + y] == num) return false; + } + } + return true; +} + +function solve(i, j) { + if(i == 8 && j == 8) { //! base case + if(grid[i][j] != 0) { + display(grid); + return; + } else { + for(let num = 1; num <= 9; num++) { + if(isSafe(i, j, num)) { + grid[i][j] = num; + display(grid); + return; + } + } + return; + } + } + if(j >= 9) { + solve(i + 1, 0); + return; + } + if(i >= 9) return; + + if(grid[i][j] == 0) { + for(let num = 1; num <= 9; num++) { + if(isSafe(i, j, num)) { + grid[i][j] = num; + solve(i, j + 1); + grid[i][j] = 0; //! reset + } + } + } else { + solve(i, j + 1); + } +} + +solve(0, 0); + \ No newline at end of file diff --git a/Arrays/tempCodeRunnerFile.cpp b/Arrays/tempCodeRunnerFile.cpp new file mode 100644 index 00000000..3d0cac8c --- /dev/null +++ b/Arrays/tempCodeRunnerFile.cpp @@ -0,0 +1,7 @@ +if (arr[i] + arr[j+1] == target) { + // cout << arr[i] << "," << arr[j+1] << endl; + // break; + // } + // else { + + // } \ No newline at end of file diff --git a/Arrays/tempCodeRunnerFile.js b/Arrays/tempCodeRunnerFile.js new file mode 100644 index 00000000..ee9e230a --- /dev/null +++ b/Arrays/tempCodeRunnerFile.js @@ -0,0 +1,9 @@ +function isValidSubsequence(array, sequence) { +// let arrIdx = 0; +// let seqIdx = 0; +// while(arrIdx < array.length && seqIdx < sequence.length) { +// if(array[arrIdx] == sequence[seqIdx]) seqIdx++; +// arrIdx++; +// } +// return seqIdx == sequence.length; +// } \ No newline at end of file diff --git a/Arrays/threeNumberSum.js b/Arrays/threeNumberSum.js new file mode 100644 index 00000000..045921a2 --- /dev/null +++ b/Arrays/threeNumberSum.js @@ -0,0 +1,59 @@ +//? https://www.algoexpert.io/questions/Three%20Number%20Sum +//! O(n^2) | space O(n) +function threeNumberSum(array, targetSum) { + array.sort( (a, b) => a - b); + const triplets = []; + + for (let i = 0; i < array.length - 2; i++) { + let left = i + 1; + let right = array.length - 1; + while (left < right) { + const currentSum = array[i] + array[left] + array[right]; + + if (currentSum === targetSum) { + triplets.push([array[i], array[left], array[right]]); + left++; right--; + } + else if (currentSum < targetSum) { + left++; + } + else if (currentSum > targetSum) { + right--; + } + } + } + return triplets; +} + +console.log(threeNumberSum(array, targetSum)); + +let array = [1, 4, 4, 5, 5, 5, 6, 6 ,11]; +array.sort( (a, b) => a - b) +let targetSum = 10; +let result = []; + + +/** +//! O(n^3) | space O(n) + +for(let i = 0; i <= array.length - 1; i++) { + let a = array[i]; + for(let j = i + 1; j <= array.length - 2; j++) { + let b = array[j]; + for(let k = j + 1; k <= array.length - 1; k++) { + let c = array[k]; + let d = a + b + c; + if(d === targetSum) { + result.push([a, b, c]); + } + } + } +} + +for(let i = 0; i < result.length; i++) { + result[i].sort( (a, b) => a - b); +} + +console.log(result); + +*/ \ No newline at end of file diff --git a/Arrays/threeSum.js b/Arrays/threeSum.js new file mode 100644 index 00000000..e69de29b diff --git a/Arrays/tournamentWinner.js b/Arrays/tournamentWinner.js new file mode 100644 index 00000000..1d5b0c80 --- /dev/null +++ b/Arrays/tournamentWinner.js @@ -0,0 +1,44 @@ +//? https://www.algoexpert.io/questions/Tournament%20Winner +//! O(n) time | O(k) space , k is the number of teams +const HOME_TEAM_WON = 1; + +function tournamentWinner(competitions, results) { + // let currentBestTeam = ''; + // const scores = {[currentBestTeam]: 0}; + // console.log(scores); + const scores = {}; + let currentBestTeam = ''; + scores[currentBestTeam] = 0; + + for(let i = 0; i < competitions.length; i++) { + let [homeTeam, awayTeam] = competitions[i]; + let result = results[i]; + const winningTeam = result == HOME_TEAM_WON ? homeTeam : awayTeam; + + updateScores(winningTeam, 3, scores); + + if(scores[winningTeam] > scores[currentBestTeam]) { + currentBestTeam = winningTeam; + } + } + console.log(scores); + console.log(currentBestTeam); + return currentBestTeam; +} + +function updateScores(team, points, scores) { + if(!(team in scores)) { + scores[team] = 0; + } + scores[team] += points; +} + +const competitions = [ + ["HTML", "C#"], + ["C#", "Python"], + ["Python", "HTML"] +] +const results = [0, 0, 1]; + + +console.log(tournamentWinner(competitions, results)); \ No newline at end of file diff --git a/Arrays/transposeMatrix.js b/Arrays/transposeMatrix.js new file mode 100644 index 00000000..7f8508e9 --- /dev/null +++ b/Arrays/transposeMatrix.js @@ -0,0 +1,39 @@ +function transposeMatrix(matrix) { + + let result = [...Array(matrix[0].length)].map(e => Array(matrix.length)); + + console.log(result); + + for(let i = 0; i < result.length; i++) { + for(let j = 0; j < result[0].length; j++) { + result[i][j] = matrix[j][i]; + } + } + return result; +} + +const matrix = [[1,4],[2,5],[3,6]]; + + + +console.log(transposeMatrix(matrix)); + + +function addMatrices(matrix1, matrix2) { + + const result = [...Array(matrix1.length)].map(e => Array(matrix1[0].length)); + + for(let i = 0; i < matrix1.length; i++) { + for(let j = 0; j < matrix1[0].length; j++) { + result[i][j] = matrix1[i][j] + matrix2[i][j]; + } + } + return result; +} + +const matrix1 = [[4, 5], + [6, 7]]; +const matrix2 = [[1, 2], + [3, 8]]; + +console.log(addMatrices(matrix1, matrix2)); \ No newline at end of file diff --git a/Arrays/twoDArray.js b/Arrays/twoDArray.js new file mode 100644 index 00000000..0d1878bc --- /dev/null +++ b/Arrays/twoDArray.js @@ -0,0 +1,15 @@ +//! 29/01/2022 + +const users = [ + ['a', 'a@gmail.com', 1 ], + ['b', 'b@gmail.com', 2 ], + ['c', 'c@gmail.com', 3 ], + ['d', 'd@gmail.com', 4 ] +]; + + +users.push([1, 2]); +users.shift(); +users.pop(); +users.unshift("newly inserted", 1, 2) +console.log(users); \ No newline at end of file diff --git a/Arrays/twoNumberSum.cpp b/Arrays/twoNumberSum.cpp new file mode 100644 index 00000000..c37ccecb --- /dev/null +++ b/Arrays/twoNumberSum.cpp @@ -0,0 +1,36 @@ + +// TODO DNF VARIANT ---> BRUTE FORCE O(n^2) + +#include +using namespace std; + +int arr[] = {3, 5, -4, 8, 11, 1, -1, 6, 2}; +int len = sizeof(arr) / sizeof(arr[0]); +int targetSum = 10; +int i = 0; +int j = len-1; +int main () { + + // for (int i = 0; i < len - 1; i++) + // { + // for (int j = i; j < len - 1; j++) { + // if (arr[i] + arr[j+1] == target) { + // cout << arr[i] << "," << arr[j+1] << endl; + // break; + // } + // } + + // } + + while ( i < j ) { + if ( arr[i] + arr[j] == targetSum) { + cout << arr[i] << "," << arr[j] << endl; + i++; + j--; + } + else if ( arr[i] + arr[j] > targetSum) { + j--; + } + else i++; + } + } \ No newline at end of file diff --git a/Arrays/twoNumberSum.js b/Arrays/twoNumberSum.js new file mode 100644 index 00000000..64e22731 --- /dev/null +++ b/Arrays/twoNumberSum.js @@ -0,0 +1,69 @@ +//! https://www.algoexpert.io/questions/Two%20Number%20Sum +//! O(nlogn) time | O(1) space +// function twoNumberSum(array, targetSum) { +// array.sort((a, b) => a - b); +// let left = 0; +// let right = array.length - 1; +// while( left < right) { +// const currentSum = array[left] + array[right]; +// if(currentSum == targetSum) { +// return [array[left], array[right]]; +// } else if(currentSum < targetSum) { +// left++; +// } else if(currentSum > targetSum) { +// right--; +// } +// } +// return []; +// } + +//! O(n) time | O(n) space +function twoNumberSum(array, targetSum) { + const nums = {}; +for(let i = 0; i < array.length; i++) { + const nums = {}; + // for(const num of array) { + // const potentialMatch = targetSum - num; + // if(potentialMatch in nums) { + // return [potentialMatch, num]; + // }else { + // nums[num] = true; + // } + // } + // return []; + for(let i = 0; i < array.length; i++) { + const num = array[i]; + const potentialMatch = targetSum - num; + if(potentialMatch in nums) { + console.log(nums) + return [nums[potentialMatch].index, i]; + } + else { + nums[num] = {num}; + nums[num].index = i + } + // console.log(nums) + } + return []; + } +} + +//! O(n^2) time | O(1) space +// function twoNumberSum(array, targetSum) { +// for(let i = 0; i < array.length; i++) { +// const firstNum = array[i]; +// for(let j = 0; j < array.length; j++) { +// const secondNum = array[j]; +// if(firstNum + secondNum == targetSum) { +// return [firstNum, secondNum]; +// } +// } +// } +// return []; +// } + +const array = [3,3]; +const target = 6; + + +console.log(twoNumberSum(array, target)); \ No newline at end of file diff --git a/Arrays/twoNumberSum.py b/Arrays/twoNumberSum.py new file mode 100644 index 00000000..37dd72bb --- /dev/null +++ b/Arrays/twoNumberSum.py @@ -0,0 +1,46 @@ +# O(n^2) | O(1) space + +# def twoNumberSum(array, targetSum): +# for i in range(len(array) - 1): +# firstNum = array[i] + +# for j in range(i + 1, len(array)): +# secondNum = array[j] +# if firstNum + secondNum == targetSum: +# return [firstNum, secondNum] +# return [] + +# USING DICTIONARY / HASH TABLE +# O(n) | O(n) space + +# def twoNumberSum(array, targetSum): +# nums = {} +# for num in array: +# potentialMatch = targetSum - num +# if potentialMatch in nums: +# return [targetSum - num, num] +# else: +# nums[num] = True +# return [] + +# USING OPTIMAL SOLUTION +# O(nLog(n)) | O(1) space + +def twoNumberSum(array, targetSum): + array.sort() + left = 0 + right = len(array) - 1 + while left < right: + currentSum = array[left] + array[right] + if currentSum == targetSum: + return [array[left], array[right]] + elif currentSum < targetSum: + left += 1 + elif currentSum > targetSum: + right += 1 + return [] + +array = [3, 5, -4, 8, 11, 1, -1, 6] +targetSum = 8 + +twoNumberSum(array, targetSum) diff --git a/Arrays/twoPointer..js b/Arrays/twoPointer..js new file mode 100644 index 00000000..fa3fbb8f --- /dev/null +++ b/Arrays/twoPointer..js @@ -0,0 +1,18 @@ +function maxSeriesOf1(arr) { + let n = arr.length; + let i = -1, j = 0; + let ans = Number.MIN_SAFE_INTEGER; + + while(i < n && j < n) { + if(arr[j] == 1) { + ans = Math.max(ans, j++ - i); + } else { + i = j++; + } + } + return ans; +} + +let arr = [1, 1, 1, 1, 1, 0, 0, 1, 1]; + +console.log(maxSeriesOf1(arr)); \ No newline at end of file diff --git a/Arrays/twoSum.js b/Arrays/twoSum.js new file mode 100644 index 00000000..003d8b01 --- /dev/null +++ b/Arrays/twoSum.js @@ -0,0 +1,24 @@ +// https://leetcode.com/problems/two-sum/submissions/ + +var twoSum = function(array, targetSum) { + const nums = {}; + for(let i = 0; i < array.length; i++) { + const num = array[i]; + const potentialMatch = targetSum - num; + if(potentialMatch in nums) { + console.log(nums); + // return [nums[potentialMatch].index, i]; + return [nums[potentialMatch][1], i]; + } + else { + // nums[num] = {num}; + // nums[num].index = i + nums[num] = [num]; + nums[num][1] = i; + } + } + console.log(nums); + return []; +}; + +console.log(twoSum([7,3,1,5], 12)); diff --git a/Arrays/validSubSequence.cpp b/Arrays/validSubSequence.cpp new file mode 100644 index 00000000..d1b44e6d --- /dev/null +++ b/Arrays/validSubSequence.cpp @@ -0,0 +1,46 @@ +#include +#include + +using namespace std; + +int main () { + + // int arr[] = {5, 1, 22, 25, 6, -1, 8, 10}; + + // int sequence[] = {5, 1, 22, 25, 6, -1, 8, 10, 12}; + + // int sequenceSize = sizeof(sequence) / sizeof(sequence[0]); + // int count = sequenceSize; + // int k = 0; + // int arrSize = sizeof(arr) / sizeof(arr[0]); + // for (int i = 0; i < arrSize; i++) + // { + // if (count != 0) { + // if (sequence[k] == arr[i]) + // { + // k++; + // count--; + // } + // } else { + // break; + // } + + // } + // if ( count == 0) { + // cout << true << endl; + // } else { + // cout << false << endl; + // } + + int arr[] = {0, 1, 2, 4, 6, 8, 10}; + vector array; + for (int i = 0; i < 7; i++) { + + array[i] = arr[i] * arr[i]; + } + + for (auto it = array.begin(); it != array.end(); it++) { + + } + return 0; +} \ No newline at end of file diff --git a/Arrays/validSubSequence.exe b/Arrays/validSubSequence.exe new file mode 100644 index 00000000..a1ab274d Binary files /dev/null and b/Arrays/validSubSequence.exe differ diff --git a/Arrays/validateSubsequence.js b/Arrays/validateSubsequence.js new file mode 100644 index 00000000..f5614ac9 --- /dev/null +++ b/Arrays/validateSubsequence.js @@ -0,0 +1,24 @@ +//! https://www.algoexpert.io/questions/Validate%20Subsequence +//! O(n) time | O(1) space +function isValidSubsequence(array, sequence) { + let seqIdx = 0; + for(const value of array) { + if(seqIdx == sequence.length) break; + if(sequence[seqIdx] == value) seqIdx++; + } return seqIdx == sequence.length; +} +//! O(n) time | O(1) space +function isValidSubsequence(array, sequence) { + let arrIdx = 0; + let seqIdx = 0; + while(arrIdx < array.length && seqIdx < sequence.length) { + if(array[arrIdx] == sequence[seqIdx]) seqIdx++; + arrIdx++; + } + return seqIdx == sequence.length; +} + +let array = [5, 1, 22, 25, 6, -1, 8, 10]; +let sequence = [1, 6, -1, 10]; + +console.log(isValidSubsequence(array, sequence)); \ No newline at end of file diff --git a/Arrays/zigzagTraversal.cpp b/Arrays/zigzagTraversal.cpp new file mode 100644 index 00000000..36cdaae3 --- /dev/null +++ b/Arrays/zigzagTraversal.cpp @@ -0,0 +1,67 @@ +#include + +using namespace std; + +int zigzagTraversal (int arr[9][9]) { + int height = sizeof(arr) / sizeof(arr[0]) - 1; + int width = sizeof(arr[0])/sizeof(arr[0][0]) - 1; + vector result = {}; + int row = 0, col = 0; + bool goingDown = true; + + while (!isOutOfBound(row, height, col, width)) { + result.push_back(arr[row][col]); + if (goingDown) { + if (col == 0 || row == height) { + goingDown = false; + if (row == height) { + col += 1; + else (col == 0) { + row += 1; + } + } else { + row += 1; + col -= 1; + } + } else { + if (row == 0 || col == width) { + goingDown = true; + if (col == width) { + row += 1; + } else { + col += 1; + } + } else { + row -= 1; + col += 1; + } + } + + } + } + return result; +} + + bool isOutOfBound(row, col, height, width) + { + return (row < 0 || row > height || col < 0 || col > width); + } +int main () { + + int arr[9][9] = { + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 } + }; + + cout << zigzagTraversal(arr[9][9]) << endl; + + + return 0; +} \ No newline at end of file diff --git a/Arrays/zigzagTraversal.exe b/Arrays/zigzagTraversal.exe new file mode 100644 index 00000000..38991c14 Binary files /dev/null and b/Arrays/zigzagTraversal.exe differ diff --git a/Arrays/zigzagTraversal.js b/Arrays/zigzagTraversal.js new file mode 100644 index 00000000..dac4a3cc --- /dev/null +++ b/Arrays/zigzagTraversal.js @@ -0,0 +1,64 @@ + let zigzagTraversal = (array) => { + const height = array.length - 1; + const width = array[0].length - 1; + const result = []; + row = 0; + col = 0; // ! O(n) time | O(n) space + goingDown = true; + + while(!(row < 0 || row > height || col < 0 || col > width)) { + result.push(array[row][col]); + + if (goingDown) { + if (col == 0 || row == height) { + goingDown = false; + if (row == height) { + col += 1; + } + else { + row += 1; + } + } + else { + row += 1; + col -= 1; + } + + } + else { + if (row == 0 || col == width) { + goingDown = true; + if (col == width) { + row += 1; + } else { + col += 1; + } + } else { + row -= 1; + col += 1; + } + + } + + } + console.log(result); +} + +function isOutOfBound (row, col, height, width) { + return !(row < 0 || row > height || col < 0 || col > width); +} + +let arr = [ + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9] + ]; +zigzagTraversal(arr); + + diff --git a/FamousAlgorithms/.DS_Store b/FamousAlgorithms/.DS_Store new file mode 100644 index 00000000..65dfc670 Binary files /dev/null and b/FamousAlgorithms/.DS_Store differ diff --git a/FamousAlgorithms/AlgoExpert/kadanesAlgorithm.js b/FamousAlgorithms/AlgoExpert/kadanesAlgorithm.js new file mode 100644 index 00000000..ef37a97f --- /dev/null +++ b/FamousAlgorithms/AlgoExpert/kadanesAlgorithm.js @@ -0,0 +1,21 @@ +//! https://leetcode.com/problems/maximum-subarray/submissions/ +//! https://www.algoexpert.io/questions/kadane's-algorithm + +console.time("runTime"); +function kadanesAlgorithm(array) { + let maxEndingHere = array[0]; + let maxSoFar = array[0]; + + for(let i = 1; i < array.length; i++) { + const num = array[i]; + maxEndingHere = Math.max(maxEndingHere + num, num); + maxSoFar = Math.max(maxSoFar, maxEndingHere); + } + return maxSoFar; +} + +const array = [3, 5, -9, 1, 3, -2, 3, 4, 7, 2, -9, 6, 3, 1, -5, 4]; + +console.log(kadanesAlgorithm(array)); + +console.timeEnd("runTime"); \ No newline at end of file diff --git a/FamousAlgorithms/StriverSheet/kadanesAlgorithm.js b/FamousAlgorithms/StriverSheet/kadanesAlgorithm.js new file mode 100644 index 00000000..5443d5ce --- /dev/null +++ b/FamousAlgorithms/StriverSheet/kadanesAlgorithm.js @@ -0,0 +1,20 @@ +//! https://leetcode.com/problems/maximum-subarray/submissions/ + +console.time("runTime"); +function kadanesAlgorithm(array) { + let maxEndingHere = array[0]; + let maxSoFar = array[0]; + + for(let i = 1; i < array.length; i++) { + const num = array[i]; + maxEndingHere = Math.max(maxEndingHere + num, num); + maxSoFar = Math.max(maxSoFar, maxEndingHere); + } + return maxSoFar; +} + +const array = [3, 5, -9, 1, 3, -2, 3, 4, 7, 2, -9, 6, 3, 1, -5, 4]; + +console.log(kadanesAlgorithm(array)); + +console.timeEnd("runTime"); \ No newline at end of file diff --git a/HashTable/.DS_Store b/HashTable/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/HashTable/.DS_Store differ diff --git a/HashTable/groupAnagrams 2.js b/HashTable/groupAnagrams 2.js new file mode 100644 index 00000000..b83c3d3b --- /dev/null +++ b/HashTable/groupAnagrams 2.js @@ -0,0 +1,17 @@ +function group(array) { //! Time O(nklogk) klogk --> sorting time for every string + let hash_map = {}; + for(let i = 0; i < array.length; i++) { + let sorted_perm = array[i].split("").sort().join(""); + if(hash_map[sorted_perm] == undefined) { + console.log(hash_map); + hash_map[sorted_perm] = [array[i]]; + console.log(hash_map); + } else { + hash_map[sorted_perm].push(array[i]); + } + } + // return hash_map; + return Object.values(hash_map); +} + +console.log((group(["bat", "ate", "eat", "tan", "nat", "tea"]))); \ No newline at end of file diff --git a/HashTable/groupAnagrams.js b/HashTable/groupAnagrams.js new file mode 100644 index 00000000..b83c3d3b --- /dev/null +++ b/HashTable/groupAnagrams.js @@ -0,0 +1,17 @@ +function group(array) { //! Time O(nklogk) klogk --> sorting time for every string + let hash_map = {}; + for(let i = 0; i < array.length; i++) { + let sorted_perm = array[i].split("").sort().join(""); + if(hash_map[sorted_perm] == undefined) { + console.log(hash_map); + hash_map[sorted_perm] = [array[i]]; + console.log(hash_map); + } else { + hash_map[sorted_perm].push(array[i]); + } + } + // return hash_map; + return Object.values(hash_map); +} + +console.log((group(["bat", "ate", "eat", "tan", "nat", "tea"]))); \ No newline at end of file diff --git a/HashTable/hashtable_implimentation 2.js b/HashTable/hashtable_implimentation 2.js new file mode 100644 index 00000000..28348bc3 --- /dev/null +++ b/HashTable/hashtable_implimentation 2.js @@ -0,0 +1,91 @@ +class HashTable { + constructor() { + this.loadFactor = 0; + this.MAX_LOAD_FACTOR = 0.5; + this.sizeOfHashTable = 2; + this.noOfElements = 0; + this.hash_table = new Array(this.sizeOfHashTable); + } + hash(key) { + let result = 0; + let prime = 5381; + for(let i = 0; i < key.length; i++) { + result = (result + (key.charCodeAt(i)*prime)%this.sizeOfHashTable)%this.sizeOfHashTable; + prime *= 5381; + } + return result; + } + rehash() { + console.log("rehashing..."); + this.sizeOfHashTable *= 2; + let old_hash_table = this.hash_table; + this.hash_table = new Array(this.sizeOfHashTable); + this.noOfElements = 0; + for(let i = 0; i < old_hash_table.length; i++) { + if(old_hash_table[i] == undefined) continue; + for(let j = 0; j < old_hash_table[i].length; j++) { + this.insert(old_hash_table[i][j][0], old_hash_table[i][j][1]); + } + } + } + insert(key, value) { + const hash_table_index = this.hash(key); + if(this.hash_table[hash_table_index] == undefined) { + this.hash_table[hash_table_index] = []; + this.hash_table[hash_table_index].push([key, value]); + } else { + for(let i = 0; i < this.hash_table[hash_table_index].length; i++) { + if(this.hash_table[hash_table_index][i][0] == key) { + console.log(this.hash_table); + this.hash_table[hash_table_index][i][1] = value; + console.log("-------------------"); + console.log(this.hash_table); + return; + } + } + this.hash_table[hash_table_index].push([key, value]); + } + this.noOfElements += 1; + this.loadFactor = this.noOfElements / this.sizeOfHashTable; + if(this.loadFactor > this.MAX_LOAD_FACTOR) { + this.rehash(); + } + } + search(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return undefined; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + console.log(hash_table[hi][i][0]); + return this.hash_table[hi][i][1]; + } + } + } + printHashTable() { + return this.hash_table; + } + remove(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return -1; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + this.noOfElements--; + return { + key: this.hash_table[hi][i].pop(), + value: this.hash_table[hi][i].pop() + } + } + } + } +} +let ht = new HashTable(); +ht.insert("a", "1"); +ht.insert("b", "2"); +ht.insert("c", "3"); +ht.insert("d", "4"); +ht.insert("a", "5"); +// console.log(ht.search("a")); + +// console.log(ht.remove("d")); +console.log(ht.printHashTable()); + diff --git a/HashTable/hashtable_implimentation.js b/HashTable/hashtable_implimentation.js new file mode 100644 index 00000000..28348bc3 --- /dev/null +++ b/HashTable/hashtable_implimentation.js @@ -0,0 +1,91 @@ +class HashTable { + constructor() { + this.loadFactor = 0; + this.MAX_LOAD_FACTOR = 0.5; + this.sizeOfHashTable = 2; + this.noOfElements = 0; + this.hash_table = new Array(this.sizeOfHashTable); + } + hash(key) { + let result = 0; + let prime = 5381; + for(let i = 0; i < key.length; i++) { + result = (result + (key.charCodeAt(i)*prime)%this.sizeOfHashTable)%this.sizeOfHashTable; + prime *= 5381; + } + return result; + } + rehash() { + console.log("rehashing..."); + this.sizeOfHashTable *= 2; + let old_hash_table = this.hash_table; + this.hash_table = new Array(this.sizeOfHashTable); + this.noOfElements = 0; + for(let i = 0; i < old_hash_table.length; i++) { + if(old_hash_table[i] == undefined) continue; + for(let j = 0; j < old_hash_table[i].length; j++) { + this.insert(old_hash_table[i][j][0], old_hash_table[i][j][1]); + } + } + } + insert(key, value) { + const hash_table_index = this.hash(key); + if(this.hash_table[hash_table_index] == undefined) { + this.hash_table[hash_table_index] = []; + this.hash_table[hash_table_index].push([key, value]); + } else { + for(let i = 0; i < this.hash_table[hash_table_index].length; i++) { + if(this.hash_table[hash_table_index][i][0] == key) { + console.log(this.hash_table); + this.hash_table[hash_table_index][i][1] = value; + console.log("-------------------"); + console.log(this.hash_table); + return; + } + } + this.hash_table[hash_table_index].push([key, value]); + } + this.noOfElements += 1; + this.loadFactor = this.noOfElements / this.sizeOfHashTable; + if(this.loadFactor > this.MAX_LOAD_FACTOR) { + this.rehash(); + } + } + search(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return undefined; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + console.log(hash_table[hi][i][0]); + return this.hash_table[hi][i][1]; + } + } + } + printHashTable() { + return this.hash_table; + } + remove(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return -1; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + this.noOfElements--; + return { + key: this.hash_table[hi][i].pop(), + value: this.hash_table[hi][i].pop() + } + } + } + } +} +let ht = new HashTable(); +ht.insert("a", "1"); +ht.insert("b", "2"); +ht.insert("c", "3"); +ht.insert("d", "4"); +ht.insert("a", "5"); +// console.log(ht.search("a")); + +// console.log(ht.remove("d")); +console.log(ht.printHashTable()); + diff --git a/HashTable/longest_substring_without_duplicates 2.js b/HashTable/longest_substring_without_duplicates 2.js new file mode 100644 index 00000000..7369eab3 --- /dev/null +++ b/HashTable/longest_substring_without_duplicates 2.js @@ -0,0 +1,17 @@ +//! O(n) time | O(min(n, a)) space +function longestSubstringWithoutDuplication(string) { + const lastSeen = {}; + let longest = [0, 1]; + let startIdx = 0; + for(let i = 0; i < string.length; i++) { + const char = string[i]; + if(char in lastSeen) { + startIdx = Math.max(startIdx, lastSeen[char] + 1); + } if(longest[1] - longest[0] < i + 1 - startIdx){ + longest = [startIdx, i+1]; + } + lastSeen[char] = i; + } + return string.slice(longest[0], longest[1]); + +} diff --git a/HashTable/longest_substring_without_duplicates.js b/HashTable/longest_substring_without_duplicates.js new file mode 100644 index 00000000..7369eab3 --- /dev/null +++ b/HashTable/longest_substring_without_duplicates.js @@ -0,0 +1,17 @@ +//! O(n) time | O(min(n, a)) space +function longestSubstringWithoutDuplication(string) { + const lastSeen = {}; + let longest = [0, 1]; + let startIdx = 0; + for(let i = 0; i < string.length; i++) { + const char = string[i]; + if(char in lastSeen) { + startIdx = Math.max(startIdx, lastSeen[char] + 1); + } if(longest[1] - longest[0] < i + 1 - startIdx){ + longest = [startIdx, i+1]; + } + lastSeen[char] = i; + } + return string.slice(longest[0], longest[1]); + +} diff --git a/HashTable/maxFrequencyCharacter 2.js b/HashTable/maxFrequencyCharacter 2.js new file mode 100644 index 00000000..8fb4f99d --- /dev/null +++ b/HashTable/maxFrequencyCharacter 2.js @@ -0,0 +1,18 @@ +function maxFreqChar(str) { + let hm = {}; + for(let i = 0; i < str.length; i++) { + if(hm[str[i]] == undefined) hm[str[i]] = 1; + else hm[str[i]] += 1; + } + let maxFreq = 0; + let ans = undefined; + for(const [key, value] of Object.entries(hm)) { + if(maxFreq < value) { + ans = value; + maxFreq = value; + } + } + return ans; +} + +console.log(maxFreqChar("aaaaaabc")); \ No newline at end of file diff --git a/HashTable/maxFrequencyCharacter.js b/HashTable/maxFrequencyCharacter.js new file mode 100644 index 00000000..8fb4f99d --- /dev/null +++ b/HashTable/maxFrequencyCharacter.js @@ -0,0 +1,18 @@ +function maxFreqChar(str) { + let hm = {}; + for(let i = 0; i < str.length; i++) { + if(hm[str[i]] == undefined) hm[str[i]] = 1; + else hm[str[i]] += 1; + } + let maxFreq = 0; + let ans = undefined; + for(const [key, value] of Object.entries(hm)) { + if(maxFreq < value) { + ans = value; + maxFreq = value; + } + } + return ans; +} + +console.log(maxFreqChar("aaaaaabc")); \ No newline at end of file diff --git a/HashTable/minimumWindowSubstring.js b/HashTable/minimumWindowSubstring.js new file mode 100644 index 00000000..ea463340 --- /dev/null +++ b/HashTable/minimumWindowSubstring.js @@ -0,0 +1,18 @@ +//! https://leetcode.com/problems/minimum-window-substring/ +//! https://www.algoexpert.io/questions/Smallest%20Substring%20Containing + +function minWindow(s, t) { + let freq = new Array(256).fill(0); + let ans = Number.MAX_SAFE_INTEGER; + for(let i = 0; i < t.length; i++) { + freq[t[i].charCodeAt(0)]++; + } + let i = 0, j = 0; + let t_length = t.length; + while(j < s.length) { + freq[s[j].charCodeAt(0)]--; + + } +} + + diff --git a/Heaps/.DS_Store b/Heaps/.DS_Store new file mode 100644 index 00000000..a96de670 Binary files /dev/null and b/Heaps/.DS_Store differ diff --git a/Heaps/buildHeap.js b/Heaps/buildHeap.js new file mode 100644 index 00000000..ef068f73 --- /dev/null +++ b/Heaps/buildHeap.js @@ -0,0 +1,31 @@ +//! 04/03/2022 +//! O(n) time | O(1) space + +function downheapify(arr, idx) { + let largestIdx = idx; + while(idx < arr.length) { + let lc = 2 * idx + 1; + let rc = 2 * idx + 2; + if(lc < arr.length && arr[lc] > arr[largestIdx]){ + largestIdx = lc; + } + if(rc < arr.length && arr[rc] > arr[largestIdx]) { + largestIdx = rc; + } + if(largestIdx == idx) break; + let temp = arr[idx]; + arr[idx] = arr[largestIdx]; + arr[largestIdx] = temp; + idx = largestIdx; + } +} + +function buildHeap(arr) { + for(let i = arr.length - 1; i >= 0; i--) { + downheapify(arr, i); + } + return arr; +} + +let arr = [7, 9, 1, 3, 10, -2, 6, 5]; +console.log(buildHeap(arr)); \ No newline at end of file diff --git a/Heaps/kth_smallest_element 2.js b/Heaps/kth_smallest_element 2.js new file mode 100644 index 00000000..e69de29b diff --git a/Heaps/kth_smallest_element.js b/Heaps/kth_smallest_element.js new file mode 100644 index 00000000..e69de29b diff --git a/Heaps/laptops_used.js b/Heaps/laptops_used.js new file mode 100644 index 00000000..f0209dd2 --- /dev/null +++ b/Heaps/laptops_used.js @@ -0,0 +1,21 @@ +//! O(nlogn) time | O(n) space - where n is the number of times +function laptopRentals(times) { + if(times.length === 0) return 0; + + let usedLaptops = 0; + const startTimes = times.map(a => a[0]).sort((a, b) => a - b); + const endTimes = times.map(a => a[1]).sort((a, b) => a- b); + + let startIterator = 0; + let endIterator = 0; + + while(startIterator < times.length) { + if(startTimes[startIterator] >= endTimes[endIterator]) { + usedLaptops--; + endIterator++; + } + usedLaptops++; + startIterator++; + } + return usedLaptops; +} \ No newline at end of file diff --git a/Heaps/maxHeap 2.js b/Heaps/maxHeap 2.js new file mode 100644 index 00000000..ece88908 --- /dev/null +++ b/Heaps/maxHeap 2.js @@ -0,0 +1,69 @@ +//! 02/03/2022 +class maxHeap { + constructor() { + this.heap = []; + } + upheapify(idx) { + if(idx == 0) return; + while(idx) { + let parent = Math.floor( (idx - 1) / 2); + if(this.heap[parent] > this.heap[idx]) { + break; + } else { + let temp = this.heap[idx]; + this.heap[idx] = this.heap[parent]; + this.heap[parent] = temp; + } + idx = parent; + } +} + downheapify(idx) { + let largestIdx = idx; + while(idx < this.heap.length) { + let lc = 2 * idx + 1; + let rc = 2 * idx + 2; + if(lc < this.heap.length && this.heap[lc] > this.heap[largestIdx]){ + largestIdx = lc; + } + if(rc < this.heap.length && this.heap[rc] > this.heap[largestIdx]) { + largestIdx = rc; + } + if(largestIdx == idx) break; + let temp = this.heap[idx]; + this.heap[idx] = this.heap[largestIdx]; + this.heap[largestIdx] = temp; + idx = largestIdx; + } + } + insert(element) { + this.heap.push(element); + this.upheapify(this.heap.length - 1); + } + getMax() { + return this.heap[0]; + } + pop() { + //! removes the root of heap + let temp = this.heap[0]; + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap[this.heap.length - 1] = temp; + this.heap.pop(); + this.downheapify(0); + } + display() { + console.log(this.heap); + } +} + +let heap = new maxHeap(); +heap.insert(10); +heap.insert(5); +heap.insert(9); +heap.insert(-2); +heap.insert(8); + +console.log(heap.getMax()); +heap.display(); +heap.pop(); +console.log(heap.getMax()); +heap.display(); \ No newline at end of file diff --git a/Heaps/maxHeap.js b/Heaps/maxHeap.js new file mode 100644 index 00000000..ece88908 --- /dev/null +++ b/Heaps/maxHeap.js @@ -0,0 +1,69 @@ +//! 02/03/2022 +class maxHeap { + constructor() { + this.heap = []; + } + upheapify(idx) { + if(idx == 0) return; + while(idx) { + let parent = Math.floor( (idx - 1) / 2); + if(this.heap[parent] > this.heap[idx]) { + break; + } else { + let temp = this.heap[idx]; + this.heap[idx] = this.heap[parent]; + this.heap[parent] = temp; + } + idx = parent; + } +} + downheapify(idx) { + let largestIdx = idx; + while(idx < this.heap.length) { + let lc = 2 * idx + 1; + let rc = 2 * idx + 2; + if(lc < this.heap.length && this.heap[lc] > this.heap[largestIdx]){ + largestIdx = lc; + } + if(rc < this.heap.length && this.heap[rc] > this.heap[largestIdx]) { + largestIdx = rc; + } + if(largestIdx == idx) break; + let temp = this.heap[idx]; + this.heap[idx] = this.heap[largestIdx]; + this.heap[largestIdx] = temp; + idx = largestIdx; + } + } + insert(element) { + this.heap.push(element); + this.upheapify(this.heap.length - 1); + } + getMax() { + return this.heap[0]; + } + pop() { + //! removes the root of heap + let temp = this.heap[0]; + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap[this.heap.length - 1] = temp; + this.heap.pop(); + this.downheapify(0); + } + display() { + console.log(this.heap); + } +} + +let heap = new maxHeap(); +heap.insert(10); +heap.insert(5); +heap.insert(9); +heap.insert(-2); +heap.insert(8); + +console.log(heap.getMax()); +heap.display(); +heap.pop(); +console.log(heap.getMax()); +heap.display(); \ No newline at end of file diff --git a/Heaps/merge_k_sorted_sub_arrays 2.js b/Heaps/merge_k_sorted_sub_arrays 2.js new file mode 100644 index 00000000..e69de29b diff --git a/Heaps/merge_k_sorted_sub_arrays.js b/Heaps/merge_k_sorted_sub_arrays.js new file mode 100644 index 00000000..e69de29b diff --git a/Heaps/merge_sorted_arrays.js b/Heaps/merge_sorted_arrays.js new file mode 100644 index 00000000..7904f1e2 --- /dev/null +++ b/Heaps/merge_sorted_arrays.js @@ -0,0 +1,42 @@ +//! O(nk) time | O(n + k) space - n is the total +//! number of array elements and k is the number or arrays +function mergeSortedArrays(arrays) { + const sortedList = []; + const elementIdxs = arrays.map(() => 0); + while(true) { + const smallestItems = []; + for(let arrayIdx = 0; arrayIdx < arrays.length; arrayIdx++) { + const relevantArray = arrays[arrayIdx]; //? [1, 5, 9, 21] + const elementIdx = elementIdxs[arrayIdx]; //? 0 + if(elementIdx === relevantArray.length) continue; + smallestItems.push( { + arrayIdx, + num: relevantArray[elementIdx], + }); + } + console.log(smallestItems.length); + console.log(smallestItems); + if(smallestItems.length === 0) break; + const nextItem = getMinValue(smallestItems); + sortedList.push(nextItem.num); + elementIdxs[nextItem.arrayIdx]++; + } + return sortedList; +} + +function getMinValue(items) { + let minValueIdx = 0; + for(let i = 1; i < items.length; i++) { + if(items[i].num < items[minValueIdx].num ) minValueIdx = i; + } + return items[minValueIdx]; +} + +let arrays = [ + [1, 5, 9, 21], + [-1, 0], + [-124, 81, 121], + [3, 6, 12 ,20, 150] +]; + +console.log(mergeSortedArrays(arrays)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/.DS_Store b/Javascript-DSA/Arrays/.DS_Store new file mode 100644 index 00000000..f88de1fe Binary files /dev/null and b/Javascript-DSA/Arrays/.DS_Store differ diff --git a/Javascript-DSA/Arrays/2dArray.js b/Javascript-DSA/Arrays/2dArray.js new file mode 100644 index 00000000..8642dfc8 --- /dev/null +++ b/Javascript-DSA/Arrays/2dArray.js @@ -0,0 +1,31 @@ +let a = [ + [1, 2, 3], + [2, 3, 4], + [3, 4, 5] +]; + +let b = [ + [1, 2, 3], + [2, 3, 4], + [3, 4, 5] +] + +function add(a, b) { + let rows = a.length; //! find rows + let cols = a[0].length; //! find columns + let c = []; + + for(let i = 0; i < rows; i++) { + c.push(Array(cols).fill(0)); + } + + for(let i = 0; i < rows; i++) { + for(let j = 0; j < cols; j++) { + c[i][j] = a[i][j] + b[i][j]; + } +} +return c; + +} + +console.log(add(a, b)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/2dConversion.js b/Javascript-DSA/Arrays/2dConversion.js new file mode 100644 index 00000000..0673bb62 --- /dev/null +++ b/Javascript-DSA/Arrays/2dConversion.js @@ -0,0 +1,43 @@ +//! 29/01/2022 convert 1D to 2D; + + + +let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + +let r = 2; +let c = 5; + +//! my logic +// function printMe(r, c) { +// let res = ""; +// for(let i = 0; i < r; i++) { +// for(let j = 0; j < c; j++) { +// res += arr[c*i + j] + " "; +// } +// res += "\n"; +// } +// return res; +// } + +// console.log(printMe(r, c)); + +//! sanket's logic +function convert(arr, r, c) { + let mat = []; + for(let i = 0; i < r; i++) { + mat.push(Array(c)); + } + let ptr = 0; + for(let i = 0; i < r; i++) { + for(let j = 0; j < c; j++) { + if(ptr < arr.length) { + mat[i][j] = arr[ptr++]; + } + + } + } + return mat; +} + +console.log(convert(arr, r, c)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/3Sum.js b/Javascript-DSA/Arrays/3Sum.js new file mode 100644 index 00000000..02db2b65 --- /dev/null +++ b/Javascript-DSA/Arrays/3Sum.js @@ -0,0 +1,31 @@ +// https://leetcode.com/problems/3sum/ +var threeSum = function(nums) { + const triplets = []; + nums.sort((a, b) => a - b); + for(let i = 0; i < nums.length - 2; i++) { + if( (i > 0) && nums[i] == nums[i - 1]) { + continue; + } + let left = i + 1; + let right = nums.length - 1; + + while(left < right) { + const currentSum = nums[i] + nums[left] + nums[right]; + if(currentSum == 0) { + triplets.push([nums[i], nums[left], nums[right]]); + while(left < right && nums[left] == nums[left + 1]) left++; + while(left < right && nums[right] == nums[right - 1]) right--; + left++; + right--; + } else if(currentSum < 0) { + left++; + } else if(currentSum > 0) { + right--; + } + } + } + return triplets; +}; +const array = [-1,0,1,2,-1,-4]; + +console.log(threeSum(array)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/4sum.js b/Javascript-DSA/Arrays/4sum.js new file mode 100644 index 00000000..97cc1a80 --- /dev/null +++ b/Javascript-DSA/Arrays/4sum.js @@ -0,0 +1,40 @@ +//https://leetcode.com/problems/4sum/ +// https://www.youtube.com/watch?v=4ggF3tXIAp0 + +function fourSum(array, targetSum) { + const quadruplets = []; + array.sort((a, b) => a - b); + const len = array.length; + for(let i = 0; i < len; i++) { + for(let j = i + 1; j < len; j++) { + const currentSum = array[i] + array[j]; + const difference = targetSum - currentSum; + + let left = j + 1; + let right = array.length- 1; + + while(left < right) { + const twoSum = array[left] + array[right]; + + if(twoSum < difference) left++; + else if(twoSum > difference) right--; + else { + quadruplets[quadruplets.length] = [array[i], array[j], array[left], array[right]]; + + while(left < right && array[left] == quadruplets[quadruplets.length - 1][2]) left++; + + while(left < right && array[right] == quadruplets[quadruplets.length - 1][3]) right--; + } + } + while(j + 1 < len && array[j + 1] == array[j]) j++; + } + while(i + 1 < len && array[i + 1] == array[i]) ; + } + return quadruplets; +} + + +const nums =[1,0,-1,0,-2,2]; +const target = 0; + +console.log(fourSum(nums, target)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/dummy.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/dummy.js new file mode 100644 index 00000000..18c8274e --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/dummy.js @@ -0,0 +1,38 @@ +var threeSum = function(nums) { + +if(nums.length < 3) return []; + + const triplets = []; + + nums.sort((a, b) => a - b); + + for(let i = 0; i < nums.length - 2; i++) { + + if( (i > 0) && nums[i] == nums[i - 1]){ + continue; + } + let left = i + 1; + let right = nums.length - 1; + + while(left < right) { + + const currentSum = nums[i] + nums[left] + nums[right]; + + if(currentSum == 0) { + triplets.push([nums[i], nums[left], nums[right]]); + while(nums[left] == nums[left + 1]) left++; + while(nums[right] == nums[right - 1]) right--; + left++; + right--; + } + if(currentSum < 0) { + left++; + } else if(currentSum > 0) { + right--; + } + } + } +return triplets; +}; + +console.log(threeSum([0,0,0,0])); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/monotonicArray.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/monotonicArray.js new file mode 100644 index 00000000..b995066c --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/monotonicArray.js @@ -0,0 +1,22 @@ + +//! O(n) time | O(1) space +function isMonotonic(array) { +if(array.length <= 2) return true; +let direction = array[1] - array[0]; +for(let i = 2; i < array.length; i++) { + if(direction == 0) { + direction = array[i] - array[i - 1]; + continue; + } + if(breaksDirection(direction, array[i - 1], array[i])) { + return false; + } + } + return true; +} + +function breaksDirection(direction, previousInt, currentInt) { + const difference = currentInt - previousInt; + if(direction > 0) return difference < 0; + return difference > 0; +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/moveElementToEnd.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/moveElementToEnd.js new file mode 100644 index 00000000..7ca4dfae --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/moveElementToEnd.js @@ -0,0 +1,12 @@ +//? https://www.algoexpert.io/questions/Move%20Element%20To%20End +//! O(n) time | O(1) space +function moveElementToEnd(array, toMove) { +let i = 0; +let j = array.length - 1; +while(i < j) { + while( i < j && array[j] == toMove) j--; + if(array[j] == toMove) [ array[i], array[j] ] = [ array[j], array[i] ]; + i++; + } return array; +} + diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/nonConstructibleChange.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/nonConstructibleChange.js new file mode 100644 index 00000000..ff6a73be --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/nonConstructibleChange.js @@ -0,0 +1,19 @@ +//? https://www.algoexpert.io/questions/Non-Constructible%20Change +let coins = [5, 7, 1, 1, 2, 3, 22]; + +//! O(nlogn) | space O(1) + +function findCoin(coins) { + coins.sort((a, b) => a - b); + + const currentChangeCreated = 0; + for(const coin in coins) { + if(coin > currentChangeCreated + 1) return currentChangeCreated + 1; + + currentChangeCreated += coins; + } +} + + + +console.log(findCoin(coins)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/smallestDifference.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/smallestDifference.js new file mode 100644 index 00000000..39141aee --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/smallestDifference.js @@ -0,0 +1,26 @@ +//? https://www.algoexpert.io/questions/Smallest%20Difference +//! O(nlog(n) + mlog(m)) time | O(1) space +function smallestDifference(arrayOne, arrayTwo) { +arrayOne.sort((a, b) => a - b); +arrayTwo.sort((a, b) => a - b); +let idxOne = 0; +let idxTwo = 0; +let smallest = Infinity; +let current = Infinity; +let smallestPair = []; +while(idxOne < arrayOne.length && idxTwo < arrayTwo.length) { + let firstNum = arrayOne[idxOne]; + let secondNum = arrayTwo[idxTwo]; + if(firstNum < secondNum) { + current = secondNum - firstNum; + idxOne++; + } else if(secondNum < firstNum) { + current = firstNum - secondNum; + idxTwo++; + } else return [firstNum, secondNum]; + if(smallest > current) { + smallest = current; + smallestPair = [firstNum, secondNum]; + } +} return smallestPair; +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/sortedSquaredArray.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/sortedSquaredArray.js new file mode 100644 index 00000000..70eff926 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/sortedSquaredArray.js @@ -0,0 +1,31 @@ +//! https://www.algoexpert.io/questions/Sorted%20Squared%20Array +//! O(nlogn) time | O(n) space +function sortedSquaredArray(array) { + const sortedSquares = new Array(array.length).fill(0); + const smallerValueIdx = 0; + const largerValueIdx = array.length - 1; + for(let idx = array.length - 1; idx >= 0; idx--) { + const smallerValue = array[smallerValueIdx]; + const largerValue = array[largerValueIdx]; + if(Math.abs(smallerValue) > Math.abs(largerValue)) { + sortedSquares[idx] = smallerValue * smallerValue; + smallerValueIdx++; + } else { + sortedSquares[idx] = largerValue * largerValue; + largerValueIdx--; + } + } + return sortedSquares; +} + + +//! O(n) time | O(n) space +function sortedSquaredArray(array) { + const sortedSquares = new Array(array.length).fill(0); + for(let idx =0; idx < array.length; idx++) { + const value = array[idx]; + sortedSquares[idx] = value * value; + } + sortedSquares.sort((a, b) => a - b); + return sortedSquares; +} diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/tempCodeRunnerFile.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/tempCodeRunnerFile.js new file mode 100644 index 00000000..ee9e230a --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/tempCodeRunnerFile.js @@ -0,0 +1,9 @@ +function isValidSubsequence(array, sequence) { +// let arrIdx = 0; +// let seqIdx = 0; +// while(arrIdx < array.length && seqIdx < sequence.length) { +// if(array[arrIdx] == sequence[seqIdx]) seqIdx++; +// arrIdx++; +// } +// return seqIdx == sequence.length; +// } \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/threeNumberSum.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/threeNumberSum.js new file mode 100644 index 00000000..045921a2 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/threeNumberSum.js @@ -0,0 +1,59 @@ +//? https://www.algoexpert.io/questions/Three%20Number%20Sum +//! O(n^2) | space O(n) +function threeNumberSum(array, targetSum) { + array.sort( (a, b) => a - b); + const triplets = []; + + for (let i = 0; i < array.length - 2; i++) { + let left = i + 1; + let right = array.length - 1; + while (left < right) { + const currentSum = array[i] + array[left] + array[right]; + + if (currentSum === targetSum) { + triplets.push([array[i], array[left], array[right]]); + left++; right--; + } + else if (currentSum < targetSum) { + left++; + } + else if (currentSum > targetSum) { + right--; + } + } + } + return triplets; +} + +console.log(threeNumberSum(array, targetSum)); + +let array = [1, 4, 4, 5, 5, 5, 6, 6 ,11]; +array.sort( (a, b) => a - b) +let targetSum = 10; +let result = []; + + +/** +//! O(n^3) | space O(n) + +for(let i = 0; i <= array.length - 1; i++) { + let a = array[i]; + for(let j = i + 1; j <= array.length - 2; j++) { + let b = array[j]; + for(let k = j + 1; k <= array.length - 1; k++) { + let c = array[k]; + let d = a + b + c; + if(d === targetSum) { + result.push([a, b, c]); + } + } + } +} + +for(let i = 0; i < result.length; i++) { + result[i].sort( (a, b) => a - b); +} + +console.log(result); + +*/ \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/tournamentWinner.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/tournamentWinner.js new file mode 100644 index 00000000..1d5b0c80 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/tournamentWinner.js @@ -0,0 +1,44 @@ +//? https://www.algoexpert.io/questions/Tournament%20Winner +//! O(n) time | O(k) space , k is the number of teams +const HOME_TEAM_WON = 1; + +function tournamentWinner(competitions, results) { + // let currentBestTeam = ''; + // const scores = {[currentBestTeam]: 0}; + // console.log(scores); + const scores = {}; + let currentBestTeam = ''; + scores[currentBestTeam] = 0; + + for(let i = 0; i < competitions.length; i++) { + let [homeTeam, awayTeam] = competitions[i]; + let result = results[i]; + const winningTeam = result == HOME_TEAM_WON ? homeTeam : awayTeam; + + updateScores(winningTeam, 3, scores); + + if(scores[winningTeam] > scores[currentBestTeam]) { + currentBestTeam = winningTeam; + } + } + console.log(scores); + console.log(currentBestTeam); + return currentBestTeam; +} + +function updateScores(team, points, scores) { + if(!(team in scores)) { + scores[team] = 0; + } + scores[team] += points; +} + +const competitions = [ + ["HTML", "C#"], + ["C#", "Python"], + ["Python", "HTML"] +] +const results = [0, 0, 1]; + + +console.log(tournamentWinner(competitions, results)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/twoNumberSum.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/twoNumberSum.js new file mode 100644 index 00000000..64e22731 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/twoNumberSum.js @@ -0,0 +1,69 @@ +//! https://www.algoexpert.io/questions/Two%20Number%20Sum +//! O(nlogn) time | O(1) space +// function twoNumberSum(array, targetSum) { +// array.sort((a, b) => a - b); +// let left = 0; +// let right = array.length - 1; +// while( left < right) { +// const currentSum = array[left] + array[right]; +// if(currentSum == targetSum) { +// return [array[left], array[right]]; +// } else if(currentSum < targetSum) { +// left++; +// } else if(currentSum > targetSum) { +// right--; +// } +// } +// return []; +// } + +//! O(n) time | O(n) space +function twoNumberSum(array, targetSum) { + const nums = {}; +for(let i = 0; i < array.length; i++) { + const nums = {}; + // for(const num of array) { + // const potentialMatch = targetSum - num; + // if(potentialMatch in nums) { + // return [potentialMatch, num]; + // }else { + // nums[num] = true; + // } + // } + // return []; + for(let i = 0; i < array.length; i++) { + const num = array[i]; + const potentialMatch = targetSum - num; + if(potentialMatch in nums) { + console.log(nums) + return [nums[potentialMatch].index, i]; + } + else { + nums[num] = {num}; + nums[num].index = i + } + // console.log(nums) + } + return []; + } +} + +//! O(n^2) time | O(1) space +// function twoNumberSum(array, targetSum) { +// for(let i = 0; i < array.length; i++) { +// const firstNum = array[i]; +// for(let j = 0; j < array.length; j++) { +// const secondNum = array[j]; +// if(firstNum + secondNum == targetSum) { +// return [firstNum, secondNum]; +// } +// } +// } +// return []; +// } + +const array = [3,3]; +const target = 6; + + +console.log(twoNumberSum(array, target)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/validateSubsequence.js b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/validateSubsequence.js new file mode 100644 index 00000000..f5614ac9 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/Two-Pointers-Approach/validateSubsequence.js @@ -0,0 +1,24 @@ +//! https://www.algoexpert.io/questions/Validate%20Subsequence +//! O(n) time | O(1) space +function isValidSubsequence(array, sequence) { + let seqIdx = 0; + for(const value of array) { + if(seqIdx == sequence.length) break; + if(sequence[seqIdx] == value) seqIdx++; + } return seqIdx == sequence.length; +} +//! O(n) time | O(1) space +function isValidSubsequence(array, sequence) { + let arrIdx = 0; + let seqIdx = 0; + while(arrIdx < array.length && seqIdx < sequence.length) { + if(array[arrIdx] == sequence[seqIdx]) seqIdx++; + arrIdx++; + } + return seqIdx == sequence.length; +} + +let array = [5, 1, 22, 25, 6, -1, 8, 10]; +let sequence = [1, 6, -1, 10]; + +console.log(isValidSubsequence(array, sequence)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/arrayOfProducts.js b/Javascript-DSA/Arrays/AlgoExpert/arrayOfProducts.js new file mode 100644 index 00000000..f894f7a2 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/arrayOfProducts.js @@ -0,0 +1,56 @@ +//! O(n) time | O(n) space +function arrayOfProducts(array) { + const products = new Array(array.length).fill(1); + + let leftRunningProduct = 1; + for(let i = 0; i < array.length; i++){ + products[i] = leftRunningProduct; + leftRunningProduct *= array[i]; + } + let rightRunningProduct = 1; + for(let i = array.length - 1; i > -1; i--) { + products[i] *= rightRunningProduct; + rightRunningProduct *= array[i]; + } +} + +//! O(n) time | O(n) space +function arrayOfProducts(array) { + const products = new Array(array.length).fill(1); + const leftProducts = new Array(array.length).fill(1); + const rightProducts = new Array(array.length).fill(1); + + let leftRunningProduct = 1; + for(let i = 0; i < array.length; i++) { + leftProducts[i] = leftRunningProduct; + leftRunningProduct *= array[i]; + } + let rightRunningProduct = 1; + for(let i = array.length - 1; i > -1; i--) { + rightProducts[i] = rightRunningProduct; + rightRunningProduct *= array[i]; + } + for(let i = 0; i < array.length; i++) { + products[i] = leftProducts[i] * rightProducts[i]; + } + return products; +} + +//! O(n^2) time | O(n) space +function arrayOfProducts1(array) { + const products = []; + + for(let i = 0; i longestRange) { + longestRange = currentLength; + bestRange = [left + 1, right - 1]; + } + } + return bestRange; +} + +// let array = [1, 11, 3, 0, 15, 5, 2, 4, 10, 7, 12, 6]; +// let array = [1, 1, 1, 3, 4]; +let array = [0, -5, 9, 19, -1, 18, 17, 2, -4, -3, 10, 3, 12, 5, 16, 4, 11, 7, -6, -7, 6, 15, 12, 12, 2, 1, 6, 13, 14, -2]; +console.log(largestRange(array)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/longestPeak.js b/Javascript-DSA/Arrays/AlgoExpert/longestPeak.js new file mode 100644 index 00000000..5d52ae8d --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/longestPeak.js @@ -0,0 +1,25 @@ +//? https://www.algoexpert.io/questions/Longest%20Peak +//! O(n) time | O(1) space +function longestPeak(array) { + let longestPeakLength = 0; + let i = 1; + while(i < array.length - 1) { + const isPeak = array[i - 1] < array[i] && array[ i + 1] < array[i]; + if(!isPeak) { + i++; + continue; + } + let leftIdx = i - 2; + while(leftIdx >= 0 && array[leftIdx] < array[leftIdx + 1] ) { + leftIdx--; + } + let rightIdx = i + 2; + while(rightIdx < array.length && array[rightIdx] < array[rightIdx - 1]) { + rightIdx++; + } + const currentPeakLength = rightIdx - leftIdx - 1 + longestPeakLength = Math.max(longestPeakLength, currentPeakLength); + i = rightIdx; + } + return longestPeakLength; +} diff --git a/Javascript-DSA/Arrays/AlgoExpert/mergeOverlappingIntervals.js b/Javascript-DSA/Arrays/AlgoExpert/mergeOverlappingIntervals.js new file mode 100644 index 00000000..ad714109 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/mergeOverlappingIntervals.js @@ -0,0 +1,25 @@ +//? https://www.algoexpert.io/questions/Merge%20Overlapping%20Intervals + //! O(nlogn) time | O(n) space +function mergeOverlappingIntervals(intervals) { +const sortedIntervals = intervals.sort((a, b) => a[0] - b[0]); + + const mergedIntervals = []; + let currentInterval = sortedIntervals[0]; + mergedIntervals.push(currentInterval); + + for(const nextInterval of sortedIntervals) { + const [_, currentIntervalEnd] = currentInterval; + const [nextIntervalStart, nextIntervalEnd] = nextInterval; + if(currentIntervalEnd >= nextIntervalStart) { + currentInterval[1] = Math.max(currentIntervalEnd, nextIntervalEnd); + } + else { + currentInterval = nextInterval; + mergedIntervals.push(currentInterval); + } + } + return mergedIntervals; +} + +console.log(mergeOverlappingIntervals([[1, 2], [3, 5], [4, 7], [6, 8], [9, 10]])); + diff --git a/Javascript-DSA/Arrays/AlgoExpert/minRewards.js b/Javascript-DSA/Arrays/AlgoExpert/minRewards.js new file mode 100644 index 00000000..3138eaa0 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/minRewards.js @@ -0,0 +1,66 @@ +//! https://leetcode.com/problems/candy/ +//! O(n) time | O(n) space +function minRewards(scores) { + let rewards = scores.map(_ => 1); + console.log(rewards); + for(let i = 1; i < scores.length; i++) { + if(scores[i] > scores[i - 1]) rewards[i] = rewards[i - 1] + 1; + } + for(let i = scores.length - 2; i >= 0; i--) { + if(scores[i] > scores[i + 1]) rewards[i] = Math.max(rewards[i], rewards[i + 1] + 1); + } + return rewards.reduce((a, b) => a + b); +} + +//! O(n) time | O(n) space +// function minRewards(scores) { +// let rewards = scores.map(_ => 1); +// const locaMinIdxs = getLocalMinIdxs(scores); +// for(const localMinIdx of locaMinIdxs) { +// expandFromLocalMinIndx(localMinIdx, scores, rewards); +// } +// return rewards.reduce((a, b) => a + b); +// } + +// function getLocalMinIdxs(array) { +// if(array.length == 1) return [0]; +// let localMinIdxs = []; +// for(let i = 0; i < array.length; i++) { +// if(i == 0 && array[i] < array[i + 1]) localMinIdxs.push(i); +// if(i == array.length - 1 && array[i] < array[i - 1]) localMinIdxs.push(i); +// if(i == 0 || i == array.length - 1) continue; +// if(array[i] < array[i + 1] && array[i] < array[i - 1]) localMinIdxs.push(i); +// } +// return localMinIdxs; +// } + +// function expandFromLocalMinIndx(localMinIdx, scores, rewards) { +// let leftIdx = localMinIdx - 1; +// while(leftIdx >= 0 && scores[leftIdx] > scores[leftIdx + 1]) { +// rewards[leftIdx] = Math.max(rewards[leftIdx], rewards[leftIdx + 1] + 1); +// leftIdx--; +// } +// let rightIdx = localMinIdx + 1; +// while(rightIdx < scores.length && scores[rightIdx] > scores[rightIdx - 1]) { +// rewards[rightIdx] = rewards[rightIdx - 1] + 1; +// rightIdx++; +// } +// } + +//! O(n^2) time | O(n) space +// function minRewards(scores) { +// let rewards = scores.map(_ => 1); +// for(let i = 1; i < scores.length; i++) { +// let j = i - 1; +// if(scores[i] > scores[j]) { +// rewards[i] = rewards[j] + 1; +// } else { +// while(j >= 0 && scores[j] > scores[j + 1]) { +// rewards[j] = Math.max(rewards[j], rewards[j + 1] + 1); +// j--; +// } +// } +// } return rewards.reduce((a, b) => a + b); +// } + +console.log(minRewards([8, 4, 2, 1, 3, 6, 7, 9, 5])); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/spiralTraverse.js b/Javascript-DSA/Arrays/AlgoExpert/spiralTraverse.js new file mode 100644 index 00000000..bf10fe5b --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/spiralTraverse.js @@ -0,0 +1,61 @@ +//? https://www.algoexpert.io/questions/Spiral%20Traverse +//! O(n) time | O(n) space +function spiralTraverse(array) { + const result = []; + let startRow = 0, + endRow = array.length - 1; + let startCol = 0, + endCol = array[0].length - 1; + + while(startRow <= endRow && startCol <= endCol) { + for(let col = startCol; col <= endCol; col++) { + result.push(array[startRow][col]); + } + for(let row = startRow + 1; row <= endRow; row++) { + result.push(array[row][endCol]); + } + for(let col = endCol - 1; col >= startCol; col--) { + /** + * Handle the edge case when there's a single row + * in the middle of the matrix. In this case, we don't + * want to double-count the values in this row, which + * we've already counted in the first for loop above. + */ + if(startRow == endRow) break; + result.push(array[endRow][col]); + } + for(let row = endRow - 1; row > startRow; row--) { + /** + * Handle the edge case when there's a single column + * in the middle of the matrix. In this case, we don't + * want to double-count the values in this column, which + * we've already counted in the second for loop above. + */ + if(startCol == endCol) break; + result.push(array[row][startCol]); + } + startRow++; + endRow--; + startCol++; + endCol--; + + } return result; +} + +const array = [ +//! [1, 2, 3, 4], +//! Test case for line no. 18 [10, 11, 12, 5], +//! startRow === endRow [9, 8, 7, 6] + +//! [1, 2, 3], +//! [12, 13, 4], +//! Test case for line no. 23 11, 14, 5], +//! startCol === endCol [10, 15, 6], +//! [9, 8, 7] + +] + +console.log(spiralTraverse(array)); + + + diff --git a/Javascript-DSA/Arrays/AlgoExpert/subarraySort.js b/Javascript-DSA/Arrays/AlgoExpert/subarraySort.js new file mode 100644 index 00000000..bfb7fc0d --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/subarraySort.js @@ -0,0 +1,32 @@ +//? https://www.algoexpert.io/questions/Subarray%20Sort +function subarraySort(array) { + let minOutOfOrder = Infinity; + let maxOutOfOrder = -Infinity; + for(let i = 0; i < array.length; i++) { + const num = array[i]; + if(isOutOfOrder(i, num, array)) { + minOutOfOrder = Math.min(minOutOfOrder, num); + maxOutOfOrder = Math.max(maxOutOfOrder, num); + } + } + if(minOutOfOrder == Infinity) return [-1, -1]; + + let subArrayLeftIdx = 0; + while(minOutOfOrder >= array[subArrayLeftIdx]) { + subArrayLeftIdx++; + } + let subArrayRightIdx = array.length - 1; + while(maxOutOfOrder <= array[subArrayRightIdx]) { + subArrayRightIdx--; + } + return [subArrayLeftIdx, subArrayRightIdx]; +} +function isOutOfOrder(i, num, array) { + if(i == 0) return num > array[i + 1]; + if(i == array.length - 1) return num < array[i - 1]; + return num > array[i + 1] || num < array[i - 1]; +} + +console.log(subarraySort([1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19])); + + diff --git a/Javascript-DSA/Arrays/AlgoExpert/tempCodeRunnerFile.js b/Javascript-DSA/Arrays/AlgoExpert/tempCodeRunnerFile.js new file mode 100644 index 00000000..0ad301a6 --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/tempCodeRunnerFile.js @@ -0,0 +1 @@ +//? https://www.algoexpert.io/questions/Four%20Number%20Sum \ No newline at end of file diff --git a/Javascript-DSA/Arrays/AlgoExpert/zigZagTraversal.js b/Javascript-DSA/Arrays/AlgoExpert/zigZagTraversal.js new file mode 100644 index 00000000..173dee2a --- /dev/null +++ b/Javascript-DSA/Arrays/AlgoExpert/zigZagTraversal.js @@ -0,0 +1,51 @@ +//! O(n) time | O(n) space +function zigzagTraversal(array) { + const height = array.length - 1; + const width = array[0].length - 1; + let row = 0; + let col = 0; + const result = []; + let goingDown = true; + + while(!isOUtOfBounds(row, col, height, width)) { + result.push(array[row][col]); + if(goingDown) { + if(col == 0 || row == height) { + goingDown = false; + if(row == height) { + col++; + } else { + row++; + } + } else { + row++; + col--; + } + } else { + if(row == 0 || col == width) { + goingDown = true; + if(col == width) { + row++; + } else { + col++; + } + } else { + row--; + col++; + } + } + } return result; +} + +function isOUtOfBounds(row, col, height, width) { + return row < 0 || row > height || col < 0 || col > width; +} + +const array = [ + [1, 3, 4, 10], + [2, 5, 9, 11], + [6, 8, 12, 15], + [7, 13, 14, 16] + ]; + + console.log(zigzagTraversal(array)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/3sum.js b/Javascript-DSA/Arrays/StriverSheet/3sum.js new file mode 100644 index 00000000..806d3e5b --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/3sum.js @@ -0,0 +1,38 @@ +//! https://leetcode.com/problems/3sum/ + +var threeSum = function(nums) { + + const triplets = []; + + nums.sort((a, b) => a - b); + + for(let i = 0; i < nums.length - 2; i++) { + + if( (i > 0) && nums[i] == nums[i - 1]) { + continue; + } + let left = i + 1; + let right = nums.length - 1; + + while(left < right) { + + const currentSum = nums[i] + nums[left] + nums[right]; + + if(currentSum == 0) { + + triplets.push([nums[i], nums[left], nums[right]]); + console.log([nums[i], nums[left], nums[right]]); + while(nums[left] == nums[left + 1]) left++; + while(nums[right] == nums[right - 1]) right--; + left++; + right--; + } else if(currentSum < 0) { + left++; + } else if(currentSum > 0) { + right--; + } + } + } + console.log(triplets); + return triplets; +}; \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/bestTimeToSellAndBuyStock.js b/Javascript-DSA/Arrays/StriverSheet/bestTimeToSellAndBuyStock.js new file mode 100644 index 00000000..d0d7350b --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/bestTimeToSellAndBuyStock.js @@ -0,0 +1,16 @@ +// https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + +// O(n) time | O(1) space +var maxProfit = function(prices) { + let maximumProfit = 0; + let minimumStockPrice = Infinity; + + for(let i = 0; i < prices.length; i++) { + const currentPrice = prices[i]; + minimumStockPrice = Math.min(minimumStockPrice, currentPrice); + maximumProfit = Math.max(maximumProfit, currentPrice - minimumStockPrice); + } + return maximumProfit; +}; + +console.log(maxProfit([7,1,5,3,6,4])); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/buyAndSellStock.js b/Javascript-DSA/Arrays/StriverSheet/buyAndSellStock.js new file mode 100644 index 00000000..650f75c8 --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/buyAndSellStock.js @@ -0,0 +1,25 @@ +function maxProfit(prices) { + let maxProfit = 0; + let minPrice = Infinity; + for(let i = 0; i < prices.length; i++) { + const currentPrice = prices[i]; + minPrice = Math.min(minPrice, currentPrice); + maxProfit = Math.max(maxProfit, currentPrice - minPrice); + } + return maxProfit; +} + +const prices = [7,1,5,3,6,4]; + +console.log(maxProfit(prices)); + +function maxProfit(prices) { + let maxProfit = 0; + for(let i = 0; i < prices.length; i++) { + for(let j = i + 1; j < prices.length; j++) { + const profit = prices[j] - prices[i]; + maxProfit = Math.max(maxProfit, profit); + } + } + return maxProfit; + } \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/kadaneAlgorithm.js b/Javascript-DSA/Arrays/StriverSheet/kadaneAlgorithm.js new file mode 100644 index 00000000..a27bd81d --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/kadaneAlgorithm.js @@ -0,0 +1,4 @@ +// https://leetcode.com/problems/maximum-subarray/ +// https://www.algoexpert.io/questions/kadane's-algorithm + +// Refer AloExpert \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/moveZeros.js b/Javascript-DSA/Arrays/StriverSheet/moveZeros.js new file mode 100644 index 00000000..ac93984d --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/moveZeros.js @@ -0,0 +1,20 @@ +// https://leetcode.com/problems/move-zeroes/submissions/ + +function nonZeros(nums) { + + if(nums.length == 0) return; + + let currentPosition = 0; + + for(const num of nums) { + if(num != 0) nums[currentPosition++] = num; + } + + while(currentPosition < nums.length) { + nums[currentPosition++] = 0; + } + + return nums; +} + + diff --git a/Javascript-DSA/Arrays/StriverSheet/nextPermutation.js b/Javascript-DSA/Arrays/StriverSheet/nextPermutation.js new file mode 100644 index 00000000..1edc8111 --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/nextPermutation.js @@ -0,0 +1,31 @@ +// https://leetcode.com/problems/next-permutation/ + + +function nextPermutation(nums) { + if(nums == null || nums.length <= 1) return nums; + + let i = nums.length - 2; + + while(i > -1 && nums[i] >= nums[i + 1]) i--; + + if(i > -1) { + let j = nums.length - 1; + while(nums[j] <= nums[i]) j--; + swap(nums, i, j); + } + + return reverse(nums, i + 1, nums.length - 1); +} + +function swap(nums, i, j) { + [ nums[i], nums[j] ] = [ nums[j], nums[i] ]; +} + +function reverse(nums, i, j) { + if(i >= j) return nums; + swap(nums, i, j); + return reverse(nums, i + 1, j - 1); + while(i < j) swap(nums, i++, j--); + return nums; +} +console.log(nextPermutation([5, 4, 3, 2, 1])); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/pascalsTriangle.js b/Javascript-DSA/Arrays/StriverSheet/pascalsTriangle.js new file mode 100644 index 00000000..93d7c965 --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/pascalsTriangle.js @@ -0,0 +1,20 @@ +//! https://leetcode.com/problems/pascals-triangle/ + +// https://takeuforward.org/data-structure/program-to-generate-pascals-triangle/ +function generate(numRows) { + var pascal = []; + for(let i = 0; i < numRows; i++) { + pascal[i] = []; + pascal[i][0] = 1; + for(let j = 1; j < i; j++) { + pascal[i][j] = pascal[i - 1][j - 1] + pascal[i - 1][j]; + } + pascal[i][i] = 1; + } + return pascal; +} + + +const numRows = 5; + +console.log(generate(numRows)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/power.js b/Javascript-DSA/Arrays/StriverSheet/power.js new file mode 100644 index 00000000..8d480c13 --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/power.js @@ -0,0 +1,22 @@ +function powerHelper(a, n) { + if (n == 1) return a; + let mid = Math.floor(n / 2); + let b = powerHelper(a, mid); + let c = b * b; + console.log(c) + if (n % 2 === 0) return c; + return a * c; +} + +function power(a, n) { + let ans; + if(n < 0) { + ans = powerHelper(a, -1 * n); + ans = 1.0 / ans; + } + else { + ans = powerHelper(a, n); + } + return ans; +} +console.log(power(2.00000, -2)); diff --git a/Javascript-DSA/Arrays/StriverSheet/rotateImage.js b/Javascript-DSA/Arrays/StriverSheet/rotateImage.js new file mode 100644 index 00000000..cc179f3e --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/rotateImage.js @@ -0,0 +1,32 @@ +//! https://leetcode.com/problems/rotate-image/ +//! https://www.geeksforgeeks.org/turn-an-image-by-90-degree/ + + +// O(n * m) time +function rotateImage(matrix) { + + let rotatedMatrix = matrix; + let len = matrix.length - 1; + + // for(let row = 0; row < matrix.length; row++) { + // for(let col = 0; col < matrix[0].length; col++) { + // rotatedMatrix[col][len - row] = matrix[row][col]; + // } + // } + // return rotatedMatrix; + + for(let row = 0; row < matrix.length; row++) + for(let col = row; col < matrix[row].length; col++) + [matrix[row][col], matrix[col][row] ]= [matrix[col][row], matrix[row][col]]; + + for(let row = 0; row < matrix.length; row++) + matrix[row].reverse(); + + return matrix; + +} + + +const matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];; + +console.log(rotateImage(matrix)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/StriverSheet/setMatrixZeroes.js b/Javascript-DSA/Arrays/StriverSheet/setMatrixZeroes.js new file mode 100644 index 00000000..088abd14 --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/setMatrixZeroes.js @@ -0,0 +1,31 @@ +//! https://leetcode.com/problems/set-matrix-zeroes/ +//! https://takeuforward.org/data-structure/set-matrix-zero/ + +// O(n * m) time | O(1) space + +console.time("runTime"); +function setMatrixZeros(matrix) { + + let col0 = 1, rows = matrix.length, cols = matrix[0].length; + + for(let i = 0; i < rows; i++) { + if(matrix[i][0] == 0) cols = 0; + for(let j = 1; j < cols; j++) { + if(matrix[i][j] == 0) { + matrix[i][0] = matrix[0][j] = 0; + } + } + } + + for(let i = rows - 1; i > -1; i--) { + for(let j = cols - 1; j > 0; j--) { + if(matrix[i][0] == 0 || matrix[0][j] == 0) { + matrix[i][j] = 0; + } + } + if(col0 == 0) matrix[i][0] = 0; + } +} +setMatrixZeros(matrix); + +console.timeEnd("runTime") diff --git a/Javascript-DSA/Arrays/StriverSheet/sortColors.js b/Javascript-DSA/Arrays/StriverSheet/sortColors.js new file mode 100644 index 00000000..a627ce94 --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/sortColors.js @@ -0,0 +1,27 @@ +// https://leetcode.com/problems/sort-colors/ + +function sortColors(nums) { + if(nums.length <= 1) return nums; + + let low = 0, mid = 0, high = nums.length - 1; + + while(mid <= high) { + const num = nums[mid]; + switch(num) { + case 0: + swap(num, low++, mid++); + break; + case 1: + mid++; + break; + case 2: + swap(num, mid, high--); + } + } + return nums; +} + +function swap(nums, i, j) { + [ nums[i], nums[j] ] = [ nums[j], nums[i] ]; +} + diff --git a/Javascript-DSA/Arrays/StriverSheet/tempCodeRunnerFile.js b/Javascript-DSA/Arrays/StriverSheet/tempCodeRunnerFile.js new file mode 100644 index 00000000..484673c6 --- /dev/null +++ b/Javascript-DSA/Arrays/StriverSheet/tempCodeRunnerFile.js @@ -0,0 +1,2 @@ + + return a * c; \ No newline at end of file diff --git a/Javascript-DSA/Arrays/androidPattern.js b/Javascript-DSA/Arrays/androidPattern.js new file mode 100644 index 00000000..d6a6edbc --- /dev/null +++ b/Javascript-DSA/Arrays/androidPattern.js @@ -0,0 +1,39 @@ +//! 28/01/2022 +let hoptable = []; + +function calcPattern(visited, curr, remain) { + if(remain == 0) return 1; + visited[curr] = true; + let ans = 0; + for(let i = 1; i <= 9; i++) { + if(!visited[i] && (hoptable[curr][i] == 0 || visited[hoptable[curr][i]] == true)) { + ans += calcPattern(visited, i, remain - 1); + } + } + visited[curr] = false; + return ans; + +} +function countPattern(m, n) { + for(let i = 0; i < 10; i++) { + hoptable.push(Array(10).fill(0)); + } + hoptable[1][3] = hoptable[3][1] = 2; + hoptable[1][7] = hoptable[7][1] = 4; + hoptable[3][9] = hoptable[9][3] = 6; + hoptable[7][9] = hoptable[9][7] = 8; + hoptable[1][9] = hoptable[9][1] = hoptable[3][7] = hoptable[7][3] = hoptable[2][8] = hoptable[8][2] = hoptable[4][6] = hoptable[6][4] = 5; + let ans = 0; + let visited = Array(9).fill(false); + for(let i = m; i <= n; i++) { + ans += calcPattern(visited, 1, i-1)*4; + ans += calcPattern(visited, 2, i-1)*4; + ans += calcPattern(visited, 5, i-1); + } + return ans; + +} + +console.log(countPattern(1,2)); + + diff --git a/Javascript-DSA/Arrays/classes.js b/Javascript-DSA/Arrays/classes.js new file mode 100644 index 00000000..81e7be8f --- /dev/null +++ b/Javascript-DSA/Arrays/classes.js @@ -0,0 +1,20 @@ +class User { + constructor(firstname = "default user", lastname = "default user", credit = NaN) { + this.firstname = firstname; + this.lastname = lastname; + this.credit = credit; + } + getFullName() { return this.firstname}; + getCredit() { return this.credit; } + editName(newName) { + const myName = newName.split(' ') + return myName; + } +} + +const user1 = new User('parma1', 'param2', 1); +const user2 = new User('param1', 'param2', 2); +const user3 = new User('param1', 'param2', 3); +const user4 = new User(); + +console.log(user4.editName("edi ted")); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/countingSort.js b/Javascript-DSA/Arrays/countingSort.js new file mode 100644 index 00000000..bab1ecd4 --- /dev/null +++ b/Javascript-DSA/Arrays/countingSort.js @@ -0,0 +1,32 @@ + function countingSort(array) { //! for only positive numbers + let outputArray = Array(array.length).fill(0); + let maxElement = Math.max(...array); //! O(n) + let n = array.length; + let frequency_array = Array(maxElement + 1).fill(0); + + //! fill the frequency array + + for(let i = 0; i < n; i++) { + + frequency_array[array[i]] += 1; + + } + //! create the prefix sum array of frequency array + for(let i = 1; i < frequency_array.length; i++) { + frequency_array[i] = frequency_array[i] + frequency_array[i - 1] ; + } + + //! fill the output array based on the correct index of last occurence of any element + + for(let i = 0; i < n; i++) { + let current_element = array[i]; + outputArray[frequency_array[current_element] - 1] = array[i]; + frequency_array[current_element] -= 1; + } + return outputArray; + } + +let array = [1, 4, 3, 2, 1, 1, 2, 3]; +let sortedArray = countingSort(array); + +console.log(sortedArray); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/diffPairExist.js b/Javascript-DSA/Arrays/diffPairExist.js new file mode 100644 index 00000000..d6d7e96b --- /dev/null +++ b/Javascript-DSA/Arrays/diffPairExist.js @@ -0,0 +1,31 @@ +function diffPair(array, k) { + let n = array.length; + let i = 1; + let j = 0; + let res = []; + + while (i < n && j < n) { + // console.log("i", i, "j",); + let diff = array[i] - array[j]; + if(diff == k) { + res.push ([array[j], array[i]]); + i++; + j++; + } else if (diff < k) { + i++; + } else if (diff > k) { + if( j + 1 != i) { + j++; + } else { + i++; + j++; + } + } + } + // return false; + return res; +} + +let array = [1, 1, 4, 6, 7, 8, 11]; + +console.log(diffPair(array, 4)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/discussion_on_push.js b/Javascript-DSA/Arrays/discussion_on_push.js new file mode 100644 index 00000000..c33379ae --- /dev/null +++ b/Javascript-DSA/Arrays/discussion_on_push.js @@ -0,0 +1,5 @@ +let arr = [1, 2, 3, 4, 5]; + +arr.push(6); + +console.log(arr); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/dummy.js b/Javascript-DSA/Arrays/dummy.js new file mode 100644 index 00000000..bf17ad31 --- /dev/null +++ b/Javascript-DSA/Arrays/dummy.js @@ -0,0 +1,28 @@ +const quadruplets = []; + array.sort((a, b) => a - b); + const len = array.length; + for(let i = 0; i < len; i++) { + for(let j = i + 1; j < len; j++) { + const currentSum = array[i] + array[j]; + const difference = targetSum - currentSum; + + let left = j + 1; + let right = len - 1; + + while(left < right) { + const twoSum = array[left] + array[right]; + + if(twoSum < difference) left++; + if(twoSum > difference) right--; + else{ + quadruplets[quadruplets.length] = [array[i], array[j], array[left], array[right]]; + while(left < right && array[left] == quadruplets[quadruplets.length - 1][2]) left++; + while(left < right && array[right] == quadruplets[quadruplets.length - 1][3]) right--; + } + } + while(j + 1 < len && array[j + 1] == array[j]) j++; + } + while(i + 1 < len && array[i + 1] == array[i]) i++; + } + return quadruplets; + \ No newline at end of file diff --git a/Javascript-DSA/Arrays/findIn2dArray.js b/Javascript-DSA/Arrays/findIn2dArray.js new file mode 100644 index 00000000..b011b3de --- /dev/null +++ b/Javascript-DSA/Arrays/findIn2dArray.js @@ -0,0 +1,45 @@ +//! 29/01/2022 +let arr = [ + [1, 2, 3, 4], + [5, 6, 7, 8], + [6, 7, 8, 9], + [7, 8, 9, 10] +]; + + function finder(row, x) { + for(let i = 3; i >= row; i--) { + if(arr[row][i] == x) { + console.log(row + 1, i + 1); + return; + } + + } + console.log("not there"); + } + +function find(x) { + let cols = arr[0].length; + if(x <= arr[0][cols - 1]) { + finder(0, x); + return; + } + if(x <= arr[1][cols - 1]) { + finder(1, x); + return; + } + if(x <= arr[2][cols - 1]) { + finder(2, x); + return; + } + if(x <= arr[3][cols - 1]) { + finder(3, x); + return; + } + console.log(-1); + +} + + +find(8.2); + + \ No newline at end of file diff --git a/Javascript-DSA/Arrays/findPair.js b/Javascript-DSA/Arrays/findPair.js new file mode 100644 index 00000000..7f70c62a --- /dev/null +++ b/Javascript-DSA/Arrays/findPair.js @@ -0,0 +1,8 @@ +function findPair(arr, x) { + if(arr.length <= 1) return -1; + + let count = 0; + + + +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/ideaoneinput.js b/Javascript-DSA/Arrays/ideaoneinput.js new file mode 100644 index 00000000..5bd6bca3 --- /dev/null +++ b/Javascript-DSA/Arrays/ideaoneinput.js @@ -0,0 +1,37 @@ +process.stdin.resume(); +process.stdin.setEncoding('utf-8'); + +let inputString = ""; +let inputString1 = ""; + +let currentLine = 0; + +process.stdin.on('data', function(input) { + inputString1 += input; + +}); + +process.stdin.on('end', function(x) { + inputString1.trim(); + inputString1 = inputString1.split("\n"); + + for(let i = 0; i < inputString1.length; i++) { + inputString += inputString1[i].trim() + ' '; + } + inputString.trim(); + inputString = inputString.split(" "); + main(); +}) +function readline() { + return result = inputString[currentLine++]; +} + +function main() { + let math = parseInt(readline()); + let physics = parseInt(readline()); + let chemistry = parseInt(readline()); + + if (math < 65 || physics < 55 || chemistry < 50 || (math + physics + chemistry < 195 && math + physics < 140)) + console.log("not eligible"); + else console.log("eligible"); +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/input.js b/Javascript-DSA/Arrays/input.js new file mode 100644 index 00000000..a68f7d44 --- /dev/null +++ b/Javascript-DSA/Arrays/input.js @@ -0,0 +1,68 @@ +/* +? process.stdin.resume(); +? process.stdin.setEncoding('utf-8'); +? +? let inputString = ""; + ! data is an event +? process.stdin.on('data', function(userInput) { +? inputString += userInput; +? console.log(inputString); +? }) +? +? process.stdin.on('end', function(x) { +? inputString.trim(); +? main(); +? }); +? +? function main() { +? +? } +? +*/ + + +process.stdin.resume(); +process.stdin.setEncoding('utf-8'); + +let inputString = ""; +let currentLine = 0; +//! data is an event +process.stdin.on('data', function(userInput) { + inputString += userInput; + // console.log(inputString); +}) + +process.stdin.on('end', function() { + inputString.trim(); + inputString = inputString.split("\n"); + main(); +}); + +function readline() { + return result = inputString[currentLine++]; //! 0++ +} + +function processArray(arr) { + let temp = arr.split(" "); + let result = []; + for(let i = 0; i < temp.length; i++) { + result.push(Number(temp[i])); + } + return result; +} + +function main() { + + let t = Number(readline()); //! here t is currentLine[0]; + + while(t > 0) { + let n = Number(readline()); + let arr = readline(); + arr = processArray(arr); + let k = Number(readline()); + console.log("length of array:", n); + console.log(typeof arr); + console.log("k is", k); + t = t - 1; + } +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/intersectionofLists.js b/Javascript-DSA/Arrays/intersectionofLists.js new file mode 100644 index 00000000..e393c7e4 --- /dev/null +++ b/Javascript-DSA/Arrays/intersectionofLists.js @@ -0,0 +1,50 @@ +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} headA + * @param {ListNode} headB + * @return {ListNode} + */ + + +function length(node) { + + let length = 0; + + while (node) { + node = node.next; + length++; + } + return length; +} +var getIntersectionNode = function(headA, headB) { + + let lengthA = length(headA); + let lengthB = length(headB); + + while (lengthA > lengthB) { + + headA = headA.next; + lengthA--; + } + + while (lengthB > lengthA) { + + headB = headB.next; + lengthB--; + } + + while (headA != headB) { + headA = headA.next; + headB = headB.next; + + } + return headA; + +}; \ No newline at end of file diff --git a/Javascript-DSA/Arrays/maps.js b/Javascript-DSA/Arrays/maps.js new file mode 100644 index 00000000..60f51abd --- /dev/null +++ b/Javascript-DSA/Arrays/maps.js @@ -0,0 +1,30 @@ +var map = new Map(); + +map.set(0, "zero"); +map.set(01, "zero"); +map.set(02, "zero"); +map.set(03, "zero"); +map.set(04, "zero"); +map.set(05, "zero"); + + +// console.log(map); + +// for (let key of map.keys()) { +// console.log(`key is : ${key}`); +// } + +// for (let value of map.values()) { +// console.log(`value is : ${value}`); +// } + +// for (let [key, value] of map) { +// console.log(`key is : ${key}, value is : ${value}`); +// } + +// map.forEach( (key, value) => { +// console.log(value, key); +// }) + +// map.delete(2); +// console.log(map); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/maxSeriesOf1.js b/Javascript-DSA/Arrays/maxSeriesOf1.js new file mode 100644 index 00000000..d37a4f1f --- /dev/null +++ b/Javascript-DSA/Arrays/maxSeriesOf1.js @@ -0,0 +1,21 @@ +function maxSeriesOf1(array) { + let n = array.length; + let i = -1, j = 0; + let ans = 0; + while(j < n && i < n) { + if(array[j] == 1) { + ans = Math.max(ans, j - i); + j++; + } + else { + i = j; + j++; + } + } + return ans; + +} + +let array = [0, 1, 0, 0]; + +console.log(maxSeriesOf1(array)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/minCoins.js b/Javascript-DSA/Arrays/minCoins.js new file mode 100644 index 00000000..31bd6675 --- /dev/null +++ b/Javascript-DSA/Arrays/minCoins.js @@ -0,0 +1,19 @@ +//! 25/01/2022 + +let n = 3; +let x = 11; +let coins = [1, 5, 7]; + +function minCoins(n) { + if(n == 0) return 0; + + let ans = Number.MAX_SAFE_INTEGER; + + for(let i = 0; i < coins.length; i++) { + if( n < coins[i]) continue; + ans = Math.min(ans, minCoins(n - coins[i])); + } + return 1 + ans; +} + +console.log(minCoins(x)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/minDigit.js b/Javascript-DSA/Arrays/minDigit.js new file mode 100644 index 00000000..6ca5e081 --- /dev/null +++ b/Javascript-DSA/Arrays/minDigit.js @@ -0,0 +1,17 @@ +//! 24/01/2022 + +function minSteps(n) { + if(n < 10) return 1; + let str = "" + n; + let noOfDigits = str.length; + let ans = Number.MAX_SAFE_INTEGER; + for(let i = 0; i < noOfDigits; i++) { + let currDigit = str[i] - '0'; + if(currDigit == 0) continue; + ans = Math.min(ans, minSteps(n - currDigit)) + } + return 1 + ans; +} + +console.log(minSteps(27)); + diff --git a/Javascript-DSA/Arrays/missingNumber.js b/Javascript-DSA/Arrays/missingNumber.js new file mode 100644 index 00000000..8efdec07 --- /dev/null +++ b/Javascript-DSA/Arrays/missingNumber.js @@ -0,0 +1,21 @@ +function findMissingNumber(array) { + array.sort((a, b) => a - b) + + for(let i = 0; i < array.length - 1; i++) { + const j = i + 1; + if(array[j] - array[i] != 1) { + return array[i] + 1; + } + } +} + +function getMissing(array, n = array.length) { + let total = Math.floor( (n + 1) * (n + 2) / 2); + for(let i = 0; i < array.length; i++) { + total -= array[i]; + } + return total +} + +const array = [1, 2, 5, 6, 7, 8, 3]; +console.log(getMissing(array)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/narcissistic.js b/Javascript-DSA/Arrays/narcissistic.js new file mode 100644 index 00000000..dfc675d5 --- /dev/null +++ b/Javascript-DSA/Arrays/narcissistic.js @@ -0,0 +1,20 @@ +//! https://relevel.com/courses/backend-development-course-0001/schedule/class-details/ae173dd6-a086-4a56-85d0-0e41f00cdf14/live-class + +let num = 10000; + +for (let n = 0; n <= num; n++) { + + let str = "" + n; + let numberOfDigits = str.length; + let temp = n; + let sum = 0; + + while (temp > 0) { + let lastDigit = temp % 10; + sum = sum + Math.pow(lastDigit, numberOfDigits); + temp = Math.floor(temp / 10); + } + if (sum == n) { + console.log(n); + } +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/palindrome.js b/Javascript-DSA/Arrays/palindrome.js new file mode 100644 index 00000000..8642e7da --- /dev/null +++ b/Javascript-DSA/Arrays/palindrome.js @@ -0,0 +1,16 @@ +//! 24/01/2022 + +function checkPalindrome(str, i, j) { + if(str[i] == str[j]) { + console.log(str[i],'--', str[j]); + if(i == j || i + 1 == j) return true; + return checkPalindrome(str, i+1, j-1); + } + return false; +} + +let str = 'ABBBBBBAABBBBBBA'; +let i = 0; +let j = str.length - 1 ; + +console.log(checkPalindrome(str, i, j)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/permutations.js b/Javascript-DSA/Arrays/permutations.js new file mode 100644 index 00000000..3c5c9400 --- /dev/null +++ b/Javascript-DSA/Arrays/permutations.js @@ -0,0 +1,26 @@ +function f(str, i) { + if(i == str.length - 1) { + console.log(str); + return; + } + let arr = Array(26).fill(false); + for(let j = i; j < str.length; j++) { + let current_char = str[j]; + + if(arr[current_char.charCodeAt(0) - 97] == false) { + arr[current_char.charCodeAt(0) - 97] = true; + swap(str, i, j); + f(str, i+1); + swap(str, i, j); + } + } +} + +function swap(str, m, n) { + let temp = str[m]; + str[m] = str[n]; + str[n] = temp; +} +let arr = ['a', 'b', 'a']; + +f(arr, 0); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/platfromJump.js b/Javascript-DSA/Arrays/platfromJump.js new file mode 100644 index 00000000..628802b2 --- /dev/null +++ b/Javascript-DSA/Arrays/platfromJump.js @@ -0,0 +1,22 @@ +//! 24/01/2022 + +function platformJump(n, k) { + if(n == 0) return 0; + if(n == 1) return Math.abs(arr[1] - arr[0]); + + let ans = Number.MAX_SAFE_INTEGER; + for(var i = 1; i <= k; i++) { + if((n - i) >= 0) { + ans = Math.min(ans, platformJump(n-i, k) + Math.abs(arr[n] - arr[n - i])); + } + } + return ans; +} + + +// let arr = [1, 3, 4, 5, 2]; +let arr = [40, 10, 20, 70, 80, 10, 20, 70, 80, 60]; +let k = 4; + +console.log(platformJump(arr.length-1, k)); +console.log(Number.MAX_SAFE_INTEGER); diff --git a/Javascript-DSA/Arrays/printBinaryWithoutConsecutive1.js.js b/Javascript-DSA/Arrays/printBinaryWithoutConsecutive1.js.js new file mode 100644 index 00000000..a2023569 --- /dev/null +++ b/Javascript-DSA/Arrays/printBinaryWithoutConsecutive1.js.js @@ -0,0 +1,19 @@ +function f(n, i, str) { + if(i == n) { + console.log(str); + return; + } + if(i > n) return; + if(str[str.length - 1] == '0') { + f(n, i + 1, str + '0'); + f(n, i + 1, str + '1'); + } else if(str[str.length - 1] == '1') { + // f(n, i + 2, str + '01'); + f(n, i + 1, str + '0'); + } +} + +let n = 4; + +f(n, 1, "0"); +f(n, 1, "1"); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/printWaveForm.js b/Javascript-DSA/Arrays/printWaveForm.js new file mode 100644 index 00000000..61d0c274 --- /dev/null +++ b/Javascript-DSA/Arrays/printWaveForm.js @@ -0,0 +1,28 @@ +let a = [ [1, 2, 3, 4], + [2, 3, 4, 5], + [3, 4, 5, 6], + [40, 50, 60, 70]]; + + + +function wavePrint(arr) { + let n = arr.length; + let m = arr[0].length; + let result = ""; + for(let col = 0; col < m; col++) { + if(col % 2 == 0) { + //! even column + for(let row = 0; row < n; row++) { + result += arr[row][col] + " "; + } + } else { + //! odd column + for(let row = n - 1; row >= 0; row--) { + result += arr[row][col] + " "; + } + } + } + return result; +} + +console.log(wavePrint(a)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/reduceArray.js b/Javascript-DSA/Arrays/reduceArray.js new file mode 100644 index 00000000..836fdd9b --- /dev/null +++ b/Javascript-DSA/Arrays/reduceArray.js @@ -0,0 +1,27 @@ +function reduceArray(array) { + + const count = {}; + const result = []; + + for(let i = 0; i < array.length; i++) { + if(!(array[i] in count)) { + count[array[i]] = 1; + } else { + count[array[i]] += 1; + } + } + for(const num in count) { + if(count[num] == 1) { + result.push(parseInt(num)) + } + if(count[num] >= 2) { + result.push(parseInt(num)) + result.push(parseInt(num)) + } + } + return result; +} + +const array = [1, 2, 2, 3, 3, 3, 4, 4 ,6]; + +console.log(reduceArray(array)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/somefile.txt b/Javascript-DSA/Arrays/somefile.txt new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/Arrays/sort012.js b/Javascript-DSA/Arrays/sort012.js new file mode 100644 index 00000000..66846899 --- /dev/null +++ b/Javascript-DSA/Arrays/sort012.js @@ -0,0 +1,25 @@ +function sortZeroOneTwo(array) { + + const counts = {0: 0, 1:0, 2:0}; + + for (let i = 0; i < array.length; i++) { + counts[array[i]] += 1; + } + let len = 0; + + for(const count in counts) { + let numCount = counts[count]; + + while(numCount >= 1) { + array[len++] = parseInt(count); + numCount--; + } + } + return array; + +} + +const array = [1, 1, 1, 2, 0, 0, 0]; + + +console.log(sortZeroOneTwo(array)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/sortedSquareArray.js b/Javascript-DSA/Arrays/sortedSquareArray.js new file mode 100644 index 00000000..947f1bf9 --- /dev/null +++ b/Javascript-DSA/Arrays/sortedSquareArray.js @@ -0,0 +1,2 @@ +let array = [-7, -5, -4, 3, 6, 8, 9]; + diff --git a/Javascript-DSA/Arrays/spiralTraverse.cpp b/Javascript-DSA/Arrays/spiralTraverse.cpp new file mode 100644 index 00000000..ec5d7325 --- /dev/null +++ b/Javascript-DSA/Arrays/spiralTraverse.cpp @@ -0,0 +1,72 @@ +#include +using namespace std; + + //! using loops O(n) time | O(n) space +vector spiralTraverse(vector> array) { + + + vector result = {}; + int startRow = 0, endRow = array.size() - 1; + int startCol = 0, endCol = array[0].size() - 1; + + while ((startRow <= endRow) && (startCol <= endCol)) { + + for (int col = startCol; col <= endCol; col++) { + result.push_back(array[startRow][col]); + } + for (int row = startRow + 1; row <= endRow; row++) { + result.push_back(array[row][endCol]); + } + for (int col = endCol - 1; col >= startCol; col--) { + result.push_back(array[endRow][col]); + } + for(int row = endRow + 1; row < startRow; row++) { + result.push_back(array[row][startCol]); + } + startRow++; + endRow--; + startCol++; + endCol-- + } + + return result; + + +} + +//! Using Recursion + + +int spiralTraverse(int array[][]) { + vector result = {}; + spiralFill(array, 0, array.size() - 1, 0, array[0].size() - 1, result); + return result; + +} + +spiralFill(int array[][], int startRow, int endRow, int startCol, endCol, vector result = {}) { + + if (startRow > endRow || startCol > endCol) { + return; + } + + for (int col = startCol; col <= endCol; col++) + { + result.push_back(array[startRow][col]); + } + for (int row = startRow + 1; row <= endRow; row++) + { + result.push_back(array[row][endCol]); + } + for (int col = endCol - 1; col >= startCol; col--) + { + result.push_back(array[endRow][col]); + } + for (int row = endRow + 1; row < startRow; row++) + { + result.push_back(array[row][startCol]); + } + spiralFill(int array[][], int startRow + 1, int endRow -1, int startCol + 1, endCol - 1, vector result = {}) +} + + diff --git a/Javascript-DSA/Arrays/subsequence.js b/Javascript-DSA/Arrays/subsequence.js new file mode 100644 index 00000000..179183c1 --- /dev/null +++ b/Javascript-DSA/Arrays/subsequence.js @@ -0,0 +1,15 @@ +// ! 25/01/2022 + +function f(str, output) { + if(str == "") { + console.log(output); + return; + } + let ch = str[0]; // ! a + let restOfTheString = str.substring(1); // ! bc + // console.log("restOfTheString",restOfTheString); + f(restOfTheString, output + ch); + f(restOfTheString, output); +} + +f("abc", ""); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/sudoku.js b/Javascript-DSA/Arrays/sudoku.js new file mode 100644 index 00000000..54655fc1 --- /dev/null +++ b/Javascript-DSA/Arrays/sudoku.js @@ -0,0 +1,78 @@ +//! 28/01/2022 + +let grid = [ + [5,3,0,0,7,0,0,0,0], + [6,0,0,1,9,5,0,0,0], + [0,9,8,0,0,0,0,6,0], + [8,0,0,0,6,0,0,0,3], + [4,0,0,8,0,3,0,0,1], + [7,0,0,0,2,0,0,0,6], + [0,6,0,0,0,0,2,8,0], + [0,0,0,4,1,9,0,0,5], + [0,0,0,0,8,0,0,7,9] +]; +function display(grid) { + let result = "__ \n" + for(let i = 0; i < 9; i++) { + for(let j = 0; j < 9; j++) { + result += grid[i][j] + " | "; + } + result += "\n"; + } + console.log(result); +} + +function isSafe(i, j, num) { //! for the ith row, go to all possible columns. + for(let c = 0; c < 9; c++) { + if(grid[i][c] == num) return false; + } + for(let r = 0; r < 9; r++) { + if(grid[r][j] == num) return false; + } + let sr = (Math.floor(i/3))*3; + let sc = (Math.floor(j/3))*3; + for(let x = 0; x < 3; x++) { + for(let y = 0; y < 3; y++) { + if(grid[sr + x][sc + y] == num) return false; + } + } + return true; +} + +function solve(i, j) { + if(i == 8 && j == 8) { //! base case + if(grid[i][j] != 0) { + display(grid); + return; + } else { + for(let num = 1; num <= 9; num++) { + if(isSafe(i, j, num)) { + grid[i][j] = num; + display(grid); + return; + } + } + return; + } + } + if(j >= 9) { + solve(i + 1, 0); + return; + } + if(i >= 9) return; + + if(grid[i][j] == 0) { + for(let num = 1; num <= 9; num++) { + if(isSafe(i, j, num)) { + grid[i][j] = num; + solve(i, j + 1); + grid[i][j] = 0; //! reset + } + } + } else { + solve(i, j + 1); + } +} + +solve(0, 0); + \ No newline at end of file diff --git a/Javascript-DSA/Arrays/tempCodeRunnerFile.cpp b/Javascript-DSA/Arrays/tempCodeRunnerFile.cpp new file mode 100644 index 00000000..3d0cac8c --- /dev/null +++ b/Javascript-DSA/Arrays/tempCodeRunnerFile.cpp @@ -0,0 +1,7 @@ +if (arr[i] + arr[j+1] == target) { + // cout << arr[i] << "," << arr[j+1] << endl; + // break; + // } + // else { + + // } \ No newline at end of file diff --git a/Javascript-DSA/Arrays/tempCodeRunnerFile.js b/Javascript-DSA/Arrays/tempCodeRunnerFile.js new file mode 100644 index 00000000..89d3b208 --- /dev/null +++ b/Javascript-DSA/Arrays/tempCodeRunnerFile.js @@ -0,0 +1 @@ + const difference = targetSum - currentSum; diff --git a/Javascript-DSA/Arrays/threeSum.js b/Javascript-DSA/Arrays/threeSum.js new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/Arrays/twoDArray.js b/Javascript-DSA/Arrays/twoDArray.js new file mode 100644 index 00000000..0d1878bc --- /dev/null +++ b/Javascript-DSA/Arrays/twoDArray.js @@ -0,0 +1,15 @@ +//! 29/01/2022 + +const users = [ + ['a', 'a@gmail.com', 1 ], + ['b', 'b@gmail.com', 2 ], + ['c', 'c@gmail.com', 3 ], + ['d', 'd@gmail.com', 4 ] +]; + + +users.push([1, 2]); +users.shift(); +users.pop(); +users.unshift("newly inserted", 1, 2) +console.log(users); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/twoNumberSum.cpp b/Javascript-DSA/Arrays/twoNumberSum.cpp new file mode 100644 index 00000000..c37ccecb --- /dev/null +++ b/Javascript-DSA/Arrays/twoNumberSum.cpp @@ -0,0 +1,36 @@ + +// TODO DNF VARIANT ---> BRUTE FORCE O(n^2) + +#include +using namespace std; + +int arr[] = {3, 5, -4, 8, 11, 1, -1, 6, 2}; +int len = sizeof(arr) / sizeof(arr[0]); +int targetSum = 10; +int i = 0; +int j = len-1; +int main () { + + // for (int i = 0; i < len - 1; i++) + // { + // for (int j = i; j < len - 1; j++) { + // if (arr[i] + arr[j+1] == target) { + // cout << arr[i] << "," << arr[j+1] << endl; + // break; + // } + // } + + // } + + while ( i < j ) { + if ( arr[i] + arr[j] == targetSum) { + cout << arr[i] << "," << arr[j] << endl; + i++; + j--; + } + else if ( arr[i] + arr[j] > targetSum) { + j--; + } + else i++; + } + } \ No newline at end of file diff --git a/Javascript-DSA/Arrays/twoNumberSum.py b/Javascript-DSA/Arrays/twoNumberSum.py new file mode 100644 index 00000000..37dd72bb --- /dev/null +++ b/Javascript-DSA/Arrays/twoNumberSum.py @@ -0,0 +1,46 @@ +# O(n^2) | O(1) space + +# def twoNumberSum(array, targetSum): +# for i in range(len(array) - 1): +# firstNum = array[i] + +# for j in range(i + 1, len(array)): +# secondNum = array[j] +# if firstNum + secondNum == targetSum: +# return [firstNum, secondNum] +# return [] + +# USING DICTIONARY / HASH TABLE +# O(n) | O(n) space + +# def twoNumberSum(array, targetSum): +# nums = {} +# for num in array: +# potentialMatch = targetSum - num +# if potentialMatch in nums: +# return [targetSum - num, num] +# else: +# nums[num] = True +# return [] + +# USING OPTIMAL SOLUTION +# O(nLog(n)) | O(1) space + +def twoNumberSum(array, targetSum): + array.sort() + left = 0 + right = len(array) - 1 + while left < right: + currentSum = array[left] + array[right] + if currentSum == targetSum: + return [array[left], array[right]] + elif currentSum < targetSum: + left += 1 + elif currentSum > targetSum: + right += 1 + return [] + +array = [3, 5, -4, 8, 11, 1, -1, 6] +targetSum = 8 + +twoNumberSum(array, targetSum) diff --git a/Javascript-DSA/Arrays/twoPointer..js b/Javascript-DSA/Arrays/twoPointer..js new file mode 100644 index 00000000..fa3fbb8f --- /dev/null +++ b/Javascript-DSA/Arrays/twoPointer..js @@ -0,0 +1,18 @@ +function maxSeriesOf1(arr) { + let n = arr.length; + let i = -1, j = 0; + let ans = Number.MIN_SAFE_INTEGER; + + while(i < n && j < n) { + if(arr[j] == 1) { + ans = Math.max(ans, j++ - i); + } else { + i = j++; + } + } + return ans; +} + +let arr = [1, 1, 1, 1, 1, 0, 0, 1, 1]; + +console.log(maxSeriesOf1(arr)); \ No newline at end of file diff --git a/Javascript-DSA/Arrays/twoSum.js b/Javascript-DSA/Arrays/twoSum.js new file mode 100644 index 00000000..003d8b01 --- /dev/null +++ b/Javascript-DSA/Arrays/twoSum.js @@ -0,0 +1,24 @@ +// https://leetcode.com/problems/two-sum/submissions/ + +var twoSum = function(array, targetSum) { + const nums = {}; + for(let i = 0; i < array.length; i++) { + const num = array[i]; + const potentialMatch = targetSum - num; + if(potentialMatch in nums) { + console.log(nums); + // return [nums[potentialMatch].index, i]; + return [nums[potentialMatch][1], i]; + } + else { + // nums[num] = {num}; + // nums[num].index = i + nums[num] = [num]; + nums[num][1] = i; + } + } + console.log(nums); + return []; +}; + +console.log(twoSum([7,3,1,5], 12)); diff --git a/Javascript-DSA/Arrays/validSubSequence.cpp b/Javascript-DSA/Arrays/validSubSequence.cpp new file mode 100644 index 00000000..d1b44e6d --- /dev/null +++ b/Javascript-DSA/Arrays/validSubSequence.cpp @@ -0,0 +1,46 @@ +#include +#include + +using namespace std; + +int main () { + + // int arr[] = {5, 1, 22, 25, 6, -1, 8, 10}; + + // int sequence[] = {5, 1, 22, 25, 6, -1, 8, 10, 12}; + + // int sequenceSize = sizeof(sequence) / sizeof(sequence[0]); + // int count = sequenceSize; + // int k = 0; + // int arrSize = sizeof(arr) / sizeof(arr[0]); + // for (int i = 0; i < arrSize; i++) + // { + // if (count != 0) { + // if (sequence[k] == arr[i]) + // { + // k++; + // count--; + // } + // } else { + // break; + // } + + // } + // if ( count == 0) { + // cout << true << endl; + // } else { + // cout << false << endl; + // } + + int arr[] = {0, 1, 2, 4, 6, 8, 10}; + vector array; + for (int i = 0; i < 7; i++) { + + array[i] = arr[i] * arr[i]; + } + + for (auto it = array.begin(); it != array.end(); it++) { + + } + return 0; +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/validSubSequence.exe b/Javascript-DSA/Arrays/validSubSequence.exe new file mode 100644 index 00000000..a1ab274d Binary files /dev/null and b/Javascript-DSA/Arrays/validSubSequence.exe differ diff --git a/Javascript-DSA/Arrays/zigzagTraversal.cpp b/Javascript-DSA/Arrays/zigzagTraversal.cpp new file mode 100644 index 00000000..36cdaae3 --- /dev/null +++ b/Javascript-DSA/Arrays/zigzagTraversal.cpp @@ -0,0 +1,67 @@ +#include + +using namespace std; + +int zigzagTraversal (int arr[9][9]) { + int height = sizeof(arr) / sizeof(arr[0]) - 1; + int width = sizeof(arr[0])/sizeof(arr[0][0]) - 1; + vector result = {}; + int row = 0, col = 0; + bool goingDown = true; + + while (!isOutOfBound(row, height, col, width)) { + result.push_back(arr[row][col]); + if (goingDown) { + if (col == 0 || row == height) { + goingDown = false; + if (row == height) { + col += 1; + else (col == 0) { + row += 1; + } + } else { + row += 1; + col -= 1; + } + } else { + if (row == 0 || col == width) { + goingDown = true; + if (col == width) { + row += 1; + } else { + col += 1; + } + } else { + row -= 1; + col += 1; + } + } + + } + } + return result; +} + + bool isOutOfBound(row, col, height, width) + { + return (row < 0 || row > height || col < 0 || col > width); + } +int main () { + + int arr[9][9] = { + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + { 1, 2, 3, 4, 5, 6, 7, 8, 9 } + }; + + cout << zigzagTraversal(arr[9][9]) << endl; + + + return 0; +} \ No newline at end of file diff --git a/Javascript-DSA/Arrays/zigzagTraversal.exe b/Javascript-DSA/Arrays/zigzagTraversal.exe new file mode 100644 index 00000000..38991c14 Binary files /dev/null and b/Javascript-DSA/Arrays/zigzagTraversal.exe differ diff --git a/Javascript-DSA/Arrays/zigzagTraversal.js b/Javascript-DSA/Arrays/zigzagTraversal.js new file mode 100644 index 00000000..dac4a3cc --- /dev/null +++ b/Javascript-DSA/Arrays/zigzagTraversal.js @@ -0,0 +1,64 @@ + let zigzagTraversal = (array) => { + const height = array.length - 1; + const width = array[0].length - 1; + const result = []; + row = 0; + col = 0; // ! O(n) time | O(n) space + goingDown = true; + + while(!(row < 0 || row > height || col < 0 || col > width)) { + result.push(array[row][col]); + + if (goingDown) { + if (col == 0 || row == height) { + goingDown = false; + if (row == height) { + col += 1; + } + else { + row += 1; + } + } + else { + row += 1; + col -= 1; + } + + } + else { + if (row == 0 || col == width) { + goingDown = true; + if (col == width) { + row += 1; + } else { + col += 1; + } + } else { + row -= 1; + col += 1; + } + + } + + } + console.log(result); +} + +function isOutOfBound (row, col, height, width) { + return !(row < 0 || row > height || col < 0 || col > width); +} + +let arr = [ + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [1, 2, 3, 4, 5, 6, 7, 8, 9] + ]; +zigzagTraversal(arr); + + diff --git a/Javascript-DSA/BinarySearchTrees/.DS_Store b/Javascript-DSA/BinarySearchTrees/.DS_Store new file mode 100644 index 00000000..c3d99512 Binary files /dev/null and b/Javascript-DSA/BinarySearchTrees/.DS_Store differ diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/.DS_Store b/Javascript-DSA/BinarySearchTrees/AlgoExpert/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/Javascript-DSA/BinarySearchTrees/AlgoExpert/.DS_Store differ diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/BSTConsruction.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/BSTConsruction.js new file mode 100644 index 00000000..aaaf4488 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/BSTConsruction.js @@ -0,0 +1,103 @@ +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } + + //! Average case: O(logn) time | O(1) space + //! worst case: O(n) time | O(1) space + insert(value) { + let currentNode = this; + while(true) { + if(value < currentNode.value ) { + if(currentNode.left == null) { + currentNode.left = new BST(value); + break; + } else { + currentNode = currentNode.left; + } + } else { + if(currentNode.right == null) { + currentNode.right = new BST(value); + break; + } else { + currentNode = currentNode.right; + } + } + } + return this; + } + +//! Average case: O(logn) time | O(1) space +//! worst case: O(n) time | O(1) space + +contains(value) { + let currentNode = this; + while(currentNode) { + if(value < currentNode.value) { + currentNode = currentNode.left; + } else if(value > currentNode) { + currentNode = currentNode.right; + } else { + return true; + } + } + return false; + } + +//! Average case: O(logn) time | O(1) space +//! worst case: O(n) time | O(1) space + +remove(value, parentNode = null) { + let currentNode = this; + while(currentNode) { + if(value < currentNode.value) { + parentNode = currentNode + currentNode = currentNode.left; + } else if(value > currentNode.value) { + parentNode = currentNode; + currentNode.right; + } else { + // node to remove + //If contains left and right + if(currentNode.left && currentNode.right) { + // get smallest value in the right subtree + currentNode.value = currentNode.right.getMinValue(); + //remove smallest value from right subtree + currentNode.right.remove(currentNode.value, currentNode); + } else if(parentNode == null) { // root node + // only left subtree + if(currentNode.left) { + currentNode.value = currentNode.left.value; + currentNode.right = currentNode.left.right; + currentNode.left = currentNode.left.left; + } else if(currentNode.right) { + currentNode.value = currentNode.right.value; + currentNode.left = currentNode.right.left; + currentNode.right = currentNode.right.right; + } else { + // only one node do nothing + } + + } // only left subtree + else if(parentNode.left == currentNode) { + parentNode.left = currentNode.left != null ? currentNode.left: currentNode.right; + } // only right subtree + else if(parentNode.right == currentNode) { + parentNode.right = currentNode.right != null ? currentNode.right: currentNode.left; + } + // we're done break the loop + break; + } + } + return this; +} +getMinValue() { + let currentNode = this; + while(currentNode.left) { + currentNode = currentNode.left; + } + return currentNode.value; +} +} \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/bstTraversal.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/bstTraversal.js new file mode 100644 index 00000000..83d4009a --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/bstTraversal.js @@ -0,0 +1,32 @@ +//! O(n) time | O(n) space +function inOrderTraverse(tree, array) { + if(!tree) return; + + inOrderTraverse(tree.left, array); + array.push(tree.value); + inOrderTraverse(tree.right, array); + + return array; +} + +//! O(n) time | O(n) space +function preOrderTraverse(tree, array) { + if(!tree) return; + + array.push(tree.value); + preOrderTraverse(tree.left, array); + preOrderTraverse(tree.right, array); + + return array; +} + +//! O(n) time | O(n) space +function postOrderTraverse(tree, array) { + if(!tree) return; + + postOrderTraverse(tree.left, array); + postOrderTraverse(tree.right, array); + array.push(tree.value); + + return array; +} \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/convertSortedArrayToBst.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/convertSortedArrayToBst.js new file mode 100644 index 00000000..daff3ddd --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/convertSortedArrayToBst.js @@ -0,0 +1,93 @@ +//! Also known as minHeightBst. +//! https://www.algoexpert.io/questions/Min%20Height%20BST +//! Google + +function minHeightBst(array) { + return constructMinHeightBst(array, 0, array.length - 1); +} + + +//! O(n) time | O(n) space | best approach +function constructMinHeightBst(array, startIdx, endIdx) { + if(endIdx < startIdx) return; + + const midIdx = Math.max((startIdx + endIdx) / 2); + const bst = new BST(array[midIdx]); + + bst.left = constructMinHeightBst(array, startIdx, midIdx - 1); + bst.left = constructMinHeightBst(array, midIdx + 1, endIdx); + + return bst; + +} + +function minHeightBst(array) { + return constructMinHeightBst(array, null, 0, array.length - 1); +} + +//! O(n) time | O(n) space +function constructMinHeightBst(array, bst, startIdx, endIdx) { + if(endIdx < startIdx) return; + + const midIdx = Math.max((startIdx + endIdx) / 2); + const newBstNode = new BST(array[midIdx]); + + if(!bst) bst = newBstNode; + else { + if(array[midIdx] < bst.value) { + bst.left = newBstNode; + bst = bst.left; + } else { + bst.right = newBstNode; + bst = bst.right; + } + } + constructMinHeightBst(array, bst, startIdx, midIdx - 1); + constructMinHeightBst(array, bst, midIdx + 1, endIdx); + + return bst; + +} + +//! O(nlogn) time | O(n) space +function constructMinHeightBst(array, bst, startIdx, endIdx) { + if(endIdx < startIdx) return; + + const midIdx = Math.max((startIdx + endIdx) / 2); + const valueToAdd = array[midIdx]; + + if(!bst) bst = new BST(valueToAdd); + else bst.insert(valueToAdd); + + constructMinHeightBst(array, bst, startIdx, midIdx - 1); + constructMinHeightBst(array, bst, midIdx + 1, endIdx); + + return bst; +} + +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } + + insert(value) { + if (value < this.value) { + if (this.left === null) { + this.left = new BST(value); + } else { + this.left.insert(value); + } + } else { + if (this.right === null) { + this.right = new BST(value); + } else { + this.right.insert(value); + } + } + } +} + +// Do not edit the line below. +exports.minHeightBst = minHeightBst; diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/findClosestValueInBst.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/findClosestValueInBst.js new file mode 100644 index 00000000..725ac955 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/findClosestValueInBst.js @@ -0,0 +1,51 @@ + +function findClosestValueInBst(tree, target) { + return findClosestValueInBstHelper(tree, target, tree.value); +} + +//! worst case O(n)time | O(1) space +//! Avg case O(nlogn) time | O(1) space +function findClosestValueInBstHelper(tree, target, closest) { + + let currentNode = tree; + + while(currentNode) { + if(Math.abs(target - closest) > Math.abs(target - currentNode.value)) { + closest = currentNode.value; + } + + if(target < currentNode.value) { + currentNode = currentNode.left; + } else if(target > currentNode.value) { + currentNode = currentNode.right; + } else { + break; + } + return closest; + } +} + +//! worst case O(n)time | O(n) space +//! Avg case O(nlogn) time | O(logn) space +function findClosestValueInBstHelper(tree, target, closest) { + if(!tree) return closest; + + if(Math.abs(target - closest) > Math.abs(target - tree.value)) { + closest = tree.value; + } + + if(target < tree.value) { + return findClosestValueInBstHelper(tree.left, target, closest); + } else if(target > tree.value) { + return findClosestValueInBstHelper(tree.right, target, closest); + } + return closest; + +} +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/kthLargestValueInBst.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/kthLargestValueInBst.js new file mode 100644 index 00000000..762d7641 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/kthLargestValueInBst.js @@ -0,0 +1,21 @@ +//! O(n) time | O(n) space | worst approach + +function findKthLargestValueInBst(tree, k) { + const sortedNodeValues = []; + inOrderTraverse(tree, sortedNodeValues); +} + +function inOrderTraverse(node, sortedNodeValues) { + if(!node) return; + + inOrderTraverse(node.left, sortedNodeValues); + sortedNodeValues.push(node.value); + inOrderTraverse(node.right, sortedNodeValues); +} +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/minHeightBst.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/minHeightBst.js new file mode 100644 index 00000000..2bfea5c4 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/minHeightBst.js @@ -0,0 +1 @@ +//! AVL Tree \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/reconstructBst.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/reconstructBst.js new file mode 100644 index 00000000..c86d48d1 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/reconstructBst.js @@ -0,0 +1,37 @@ +//! aka pre-order to BST + +//! O(n) time | O(n) space + +class BST { + constructor(value, left = null, right = null) { + this.value = value; + this.left = left; + this.right = right; + } +} + +class TreeInfo { + constructor(rootIdx) { + this.rootIdx = rootIdx; + } +} + +function reconstructBst(preOrderTraversalValues) { + const treeInfo = new TreeInfo(0); + return reconstructBstFromRange(-Infinity, Infinity, preOrderTraversalValues, treeInfo); +} + +function reconstructBstFromRange(lowerBound, upperBound, preOrderTraversalValues, currentSubtreeInfo) { + if(currentSubtreeInfo.rootIdx == preOrderTraversalValues.length) return null; + + const rootValue = preOrderTraversalValues[currentSubtreeInfo.rootIdx]; + if(rootValue < lowerBound || rootValue >= upperBound) return null; + + currentSubtreeInfo.rootIdx++; + + const leftSubtree = reconstructBstFromRange(lowerBound, rootValue, preOrderTraversalValues, currentSubtreeInfo); + const rightSubtree = reconstructBstFromRange(rootValue, upperBound, preOrderTraversalValues, currentSubtreeInfo); + + return new BST(rootValue, leftSubtree, rightSubtree); +} + diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/rightSmallerThan.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/rightSmallerThan.js new file mode 100644 index 00000000..9e5f82a0 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/rightSmallerThan.js @@ -0,0 +1,68 @@ +//! https://leetcode.com/problems/count-of-smaller-numbers-after-self/ +//! https://www.algoexpert.io/questions/Right Smaller Than + +//! Avg case: O(nlog(n)) time | O(n) space +//! Worst case: O(n^2) time | O(n) space + +function rightSmallerThan(array) { + if(array.length == 0) return []; + + const lastIdx = array.length - 1; + const bst = new SpecialBST(array[lastIdx], lastIdx, 0); + for(let i = array.length - 2; i > -1; i--) { + bst.insert(array[i], i); + } + + const rightSmallerCounts = array.slice(); + getRightSmallerCounts(bst, rightSmallerCounts); + return rightSmallerCounts; +} + +function getRightSmallerCounts(bst, rightSmallerCounts) { + if(bst == null) return; + rightSmallerCounts[bst.idx] = bst.numSmallerAtInsertTime; + getRightSmallerCounts(bst.left, rightSmallerCounts); + getRightSmallerCounts(bst.right, rightSmallerCounts); +} + +class SpecialBST { + constructor(value, idx, numSmallerAtInsertTime) { + this.value = value; + this.idx = idx; + this.numSmallerAtInsertTime = numSmallerAtInsertTime; + this.leftSubtreeSize = 0; + this.left = null; + this.right = null; + } + + insert(value, idx, numSmallerAtInsertTime = 0) { + if(value < this.value) { + this.leftIdxSubtree++; + if(this.left == null) { + this.left = new SpecialBST(value, idx, numSmallerAtInsertTime); + } else { + this.left.insert(value, idx, numSmallerAtInsertTime); + } + } else { + if(value > this.value) numSmallerAtInsertTime++; + if(this.right = null) { + this.right = new SpecialBST(value, idx, numSmallerAtInsertTime); + } else { + this.right.insert(value, idx, numSmallerAtInsertTime); + } + } + } +} + +//! O(n^2) time | O(n) space +function rightSmallerThan(array) { + const rightSmallerCounts = []; + for(let i = 0; i < array.length; i++) { + let rightSmallerCount = 0; + for(let j = i + 1; j < array.length; j++) { + if(array[i] > array[j]) rightSmallerCount++; + } + rightSmallerCounts.push(rightSmallerCount); + } + return rightSmallerCounts; +} \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/sameBsts.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/sameBsts.js new file mode 100644 index 00000000..37c1d523 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/sameBsts.js @@ -0,0 +1,39 @@ +//! https://www.algoexpert.io/questions/Same%20BSTs +//! O(n^2) time | O(n^2) space + +function sameBsts(arrayOne, arrayTwo) { + + if(arrayOne.length != arrayTwo.length) return false; + + if(arrayOne.length == 0 && arrayTwo.length == 0) return true; + + if(arrayOne[0] != arrayTwo[0]) return false; + + const leftOne = getSmaller(arrayOne); + const leftTwo = getSmaller(arrayTwo); + + const rightOne = getBigger(arrayOne); + const rightTwo = getBigger(arrayTwo); + + return sameBsts(leftOne, leftTwo) && sameBsts(rightOne, rightTwo); + + +} + +function getSmaller(array) { + const smaller = []; + + for(let i = 1; i < array.length; i++) { + if(array[i] < array[0]) smaller.push(array[i]); + } + return smaller; +} + +function getBigger(array) { + const bigger = []; + + for(let i = 1; i < array.length; i++) { + if(array[i] >= array[0]) bigger.push(array[i]); + } + return bigger; +} \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/validateBst.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/validateBst.js new file mode 100644 index 00000000..2d32e7f8 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/validateBst.js @@ -0,0 +1,21 @@ +// ! O(n) time | O(d) space d = depth/height of tree + +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +function validateBst(tree) { + return validateBstHelper(tree, -Infinity, Infinity); +} + +function validateBstHelper(tree, minValue, maxValue) { + if(!tree) return true; + + if(tree.value < minValue || tree.value >= maxValue) return false; + const isLeftValid = validateBstHelper(tree.left, minValue, tree.value); + return isLeftValid && validateBstHelper(tree.right, tree.value, maxValue); +} \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/AlgoExpert/validateThreeNodes.js b/Javascript-DSA/BinarySearchTrees/AlgoExpert/validateThreeNodes.js new file mode 100644 index 00000000..372777af --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/AlgoExpert/validateThreeNodes.js @@ -0,0 +1,18 @@ + +//! O(h) time | (h) space +function validateThreeNodes(nodeOne, nodeTwo, nodeThree) { + + if(isDescedant(nodeTwo, nodeOne)) return isDescedant(nodeTwo, nodeThree); + + if(isDescedant(nodeTwo, nodeThree)) return isDescedant(nodeOne, nodeTwo); + + return false; +} + +function isDescedant(node, target) { + if(!node) return false; + + if(node == target) return true; + + return target.value < node.value ? isDescedant(node.left, target) : isDescedant(node.right, target); +} \ No newline at end of file diff --git a/Javascript-DSA/BinarySearchTrees/greatesstSumTree.js b/Javascript-DSA/BinarySearchTrees/greatesstSumTree.js new file mode 100644 index 00000000..23681d20 --- /dev/null +++ b/Javascript-DSA/BinarySearchTrees/greatesstSumTree.js @@ -0,0 +1,43 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +function preOrder(root) { + if(root == null) return; + console.log(root.data); + preOrder(root.left); + preOrder(root.right); +} + +let sum_of_nodes = 0; +function greatestSumTree(root) { + if(root == null) return; + greatestSumTree(root.right); + sum_of_nodes += root.data; + root.data = sum_of_nodes; + greatestSumTree(root.left); + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +preOrder(root); +console.log("-->"); +greatestSumTree(root); +console.log("-->"); +preOrder(root); diff --git a/Javascript-DSA/BinaryTrees/.DS_Store b/Javascript-DSA/BinaryTrees/.DS_Store new file mode 100644 index 00000000..a2f731ab Binary files /dev/null and b/Javascript-DSA/BinaryTrees/.DS_Store differ diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/allKindsOfNodesDepths.js b/Javascript-DSA/BinaryTrees/AlgoExpert/allKindsOfNodesDepths.js new file mode 100644 index 00000000..73c16703 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/allKindsOfNodesDepths.js @@ -0,0 +1,11 @@ +//! o(n^2) time | O(n) space + +function allKindsOfNodeDepths(root) { + if(!root) return 0; + return allKindsOfNodeDepths(root.left) + allKindsOfNodeDepths(root.right) + nodeDepths(root); +} + +function nodeDepths(root, depth = 0) { + if(!root) return 0; + return depth + nodeDepths(root.left, depth + 1) + nodeDepths(root.right, depth + 1); +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/binaryTreeDiameter.js b/Javascript-DSA/BinaryTrees/AlgoExpert/binaryTreeDiameter.js new file mode 100644 index 00000000..3d91779f --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/binaryTreeDiameter.js @@ -0,0 +1,36 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +class TreeInfo { + constructor(diameter, height) { + this.diameter = diameter; + this.height = height; + } +} + +//! O(n) time | O(h) space +function binaryTreeDiameter(tree) { + return getTreeInfo(tree).diameter; +} + +function getTreeInfo(tree) { + + if(!tree) return new TreeInfo(0, 0); + + const leftTreeInfo = getTreeInfo(tree.left); + const rightTreeInfo = getTreeInfo(tree.right); + + const longestPathThroughRoot = leftTreeInfo.height + rightSubTree.height; + const maxDiameterSoFar = Math.max(leftTreeInfo.diameter, rightTreeInfo.diameter); + + const currentDiameter = Math.max(maxDiameterSoFar, longestPathThroughRoot); + const currentHeight = 1 + Math.max(leftTreeInfo.height, rightTreeInfo.height); + + return new TreeInfo(currentDiameter, currentHeight); +} + diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/branchSums.js b/Javascript-DSA/BinaryTrees/AlgoExpert/branchSums.js new file mode 100644 index 00000000..43f4df16 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/branchSums.js @@ -0,0 +1,52 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +function branchSums(root) { + + const sums = []; + calculateBranchSums(root, 0, sums); + + return sums; + +} + + +function calculateBranchSums(node, runningSum, sums) { + + if(!node) return; + + const newRunningSum = runningSum + node.value; + + + if(!node.left && !node.right) { + sums.push(newRunningSum); + return; + } + calculateBranchSums(node.left, newRunningSum, sums); + calculateBranchSums(node.right, newRunningSum, sums); +} + + +const root = new BinaryTree(1); + +root.left = new BinaryTree(2); +root.right = new BinaryTree(3); + +root.left.left = new BinaryTree(4); +root.left.right = new BinaryTree(5); + +root.left.right.left = new BinaryTree(10); + +root.left.left.left = new BinaryTree(8); +root.left.left.right = new BinaryTree(9); + +root.right.left = new BinaryTree(6); +root.right.right = new BinaryTree(7); + + +console.log(branchSums(root)); \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/campareLeafTraversal.js b/Javascript-DSA/BinaryTrees/AlgoExpert/campareLeafTraversal.js new file mode 100644 index 00000000..7539f6d5 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/campareLeafTraversal.js @@ -0,0 +1,41 @@ +//! https://www.algoexpert.io/questions/Compare%20Leaf%20Traversal + +//! Google on-site + +//! O(n + m) time | O(max(h1, h2)) space + +function compareLeafTraversal(tree1, tree2) { + const [tree1LeafNodesLinkedList, _1] = connectNodes(tree1); + const [tree2LeafNodesLinkedList, _2] = connectNodes(tree2); + + let list1CurrentNode = tree1LeafNodesLinkedList; + let list2CurrentNode = tree2LeafNodesLinkedList; + + while(list1CurrentNode && list1CurrentNode) { + if(list1CurrentNode.value != list2CurrentNode.value) return false; + + list1CurrentNode = list1CurrentNode.right; + list2CurrentNode = list2CurrentNode.right; + } + return !list1CurrentNode && !list2CurrentNode; +} + +function connectNodes(currentNode, head = null, previousNode = null) { + if(!currentNode) return [head, previousNode]; + + if(isLeafNode(currentNode)) { + if(previousNode == null) { + head = currentNode; + } else { + previousNode.right = currentNode; + } + previousNode = currentNode; + } + + const [leftHead, leftPreviousNode] = connectNodes(currentNode.left, head, previousNode); + return connectNodes(currentNode.right, leftHead, leftPreviousNode); +} + +function isLeafNode(node) { + return !node.left && !node.right; +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/findNodesDistanceK.js b/Javascript-DSA/BinaryTrees/AlgoExpert/findNodesDistanceK.js new file mode 100644 index 00000000..f0d2a5b5 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/findNodesDistanceK.js @@ -0,0 +1,50 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = left; + this.right = right; + } +} + +//! O(n) time | O(n) space + +function findNodesDistanceK(tree, target, k) { + const nodesDistanceK = []; + findNodesDistanceKHelper(tree, target, k, nodesDistanceK); + return nodesDistanceK; +} + +function findNodesDistanceKHelper(node, target, k, nodesDistanceK) { + + if(!node) return -1; + + if(node == target) { + addSubtreeNodesAtDistanceK(node, 0, k, nodesDistanceK); + return 1; + } + + const leftDistance = findNodesDistanceKHelper(node.left, target, k, nodesDistanceK); + const rightDistance = findNodesDistanceKHelper(node.right, target, k, nodesDistanceK); + + if(leftDistance == k || rightDistance == k) nodesDistanceK.push(node.value); + + if(leftDistance != -1) { + addSubtreeNodesAtDistanceK(node.right, leftDistance + 1, k, nodesDistanceK); + return leftDistance + 1; + } + if(rightDistance != -1) { + addSubtreeNodesAtDistanceK(node.left, rightDistance + 1, k, nodesDistanceK); + return rightDistance + 1; + } + return -1; +} + +function addSubtreeNodesAtDistanceK(node, distance, k, nodesDistanceK) { + if(!node) return; + + if(distance == k) nodesDistanceK.push(node.value); + else { + addSubtreeNodesAtDistanceK(node.left, distance + 1, k, nodesDistanceK); + addSubtreeNodesAtDistanceK(node.right, distance + 1, k, nodesDistanceK); + } +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/findSuccessor.js b/Javascript-DSA/BinaryTrees/AlgoExpert/findSuccessor.js new file mode 100644 index 00000000..f1db7933 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/findSuccessor.js @@ -0,0 +1,65 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + this.parent = null; + } +} + +//! O(n) time | O(1) space + +function findSuccessor(tree, node) { + + if(node.right) return getLeftmostChild(node.right); + + return getRightmostParent(node); +} + +function getLeftmostChild(node) { + let currentNode = node; + + while(currentNode.left) { + currentNode = currentNode.left; + } + return currentNode; +} + +function getRightmostParent(node) { + const currentNode = node; + + while(currentNode.parent && currentNode.parent.right == currentNode) { + currentNode = currentNode.parent; + } + return currentNode.parent; +} + + +//! O(n) time | O(h) space +function findSuccessor(tree, node) { + + const inOrderTraversalOrder = getInorderTraversalOrder(tree); + + for(let idx = 0; idx < inOrderTraversalOrder.length; idx++) { + const currentNode = inOrderTraversalOrder[idx]; + + if(currentNode != node) continue; + + if(idx == inOrderTraversalOrder.length - 1) return null; + + return inOrderTraversalOrder[idx + 1]; + } + + +} + +function getInorderTraversalOrder(node, order = []) { + + if(!node) return order; + + getInorderTraversalOrder(node.left, order); + order.push(node); + getInorderTraversalOrder(node.right, order); + + return order; +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/flattenBinaryTree.js b/Javascript-DSA/BinaryTrees/AlgoExpert/flattenBinaryTree.js new file mode 100644 index 00000000..705c5f7b --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/flattenBinaryTree.js @@ -0,0 +1,59 @@ +// ! https://www.algoexpert.io/questions/Flatten%20Binary%20Tree + + +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +//! O(n) time | O(d) space d - depth of binary tree +function flattenBinaryTree(root) { + const [leftMost, _] = flattenTree(root); + return leftMost; +} + +function flattenTree(node) { + let leftMost, rightMost; + if(!node.left) leftMost = node; + else { + const [leftSubtreeLeftMost, leftSubtreeRightMost] = flattenTree(node.left); + connectNodes(leftSubtreeRightMost, node); + leftMost = leftSubtreeLeftMost; + } + if(!node.right) rightMost = node; + else { + const [rightSubtreeLeftMost, rightSubtreeRightMost] = flattenTree(node.right); + connectNodes(node, rightSubtreeLeftMost); + rightMost = rightSubtreeRightMost; + } + return [leftMost, rightMost]; +} + +function connectNodes(left, right) { + left.right = right; + right.left = left; +} + +//! O(n) time | O(n) space +function flattenBinaryTree(root) { + const inOrderNodes = getNodesInorder(root, []); + for(let i = 0; i < inOrderNodes.length - 1; i++) { + const leftNode = inOrderNodes[i]; + const rightNode = inOrderNodes[i + 1]; + leftNode.right = rightNode; + rightNode.left = leftNode; + } + return inOrderNodes[0]; +} + +function inOrderNodes(tree, array) { + if(!tree) return; + inOrderNodes(tree.left, array); + array.push(tree); + inOrderNodes(tree.right, array); + return array; +} + diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/flattenBinaryTree_leetcode.js b/Javascript-DSA/BinaryTrees/AlgoExpert/flattenBinaryTree_leetcode.js new file mode 100644 index 00000000..5b168ff0 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/flattenBinaryTree_leetcode.js @@ -0,0 +1,38 @@ +//! https://leetcode.com/problems/flatten-binary-tree-to-linked-list/ + +//! RIGHT ROOT LEFT +//! O(n) time | O(n) space + +//! REVERSE POST ORDER +let previousNode = null; +function flatten(node) { + if(!node) return; + + flatten(node.right); + flatten(node.left); + + node.right = previousNode; + node.left = null; + previousNode = node; +} + +//! O(n) time O(1) space +function flatten(root) { + let currentNode = root; + let prev = null; + while(currentNode) { + if(currentNode.left) { + prev = currentNode.left; + while(prev.right) { + prev = prev.right; + } + prev.right = currentNode.right; + currentNode.right = currentNode.left; + currentNode.left = null; + } + currentNode = currentNode.right; + } +}; + + + diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/heightBalancedBinaryTree.js b/Javascript-DSA/BinaryTrees/AlgoExpert/heightBalancedBinaryTree.js new file mode 100644 index 00000000..b36963aa --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/heightBalancedBinaryTree.js @@ -0,0 +1,36 @@ +class Tree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +class TreeInfo { + constructor(isBalanced, height) { + this.isBalanced = isBalanced; + this.height = height; + } +} + +//! O(n) time | O(h) space +function heightBalancedBinaryTree(tree) { + const treeInfo = getTreeInfo(tree); + return treeInfo.isBalanced; +} + +function getTreeInfo(tree) { + if(!tree) return new TreeInfo(true, -1); + + const leftSubtreeInfo = getLeftSubtreeInfo(tree.left); + const rightSubtreeInfo = getLeftSubtreeInfo(tree.right); + + const isBalanced = + leftSubtreeInfo.isBalanced && + rightSubtreeInfo.isBalanced && + Math.abs(leftSubtreeInfo.height - rightSubtreeInfo.height) <= 1; + + const height = Math.max(leftSubtreeInfo.height, rightSubtreeInfo.height) + 1; + + return new TreeInfo(isBalanced, height); +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/invertBinaryTree.js b/Javascript-DSA/BinaryTrees/AlgoExpert/invertBinaryTree.js new file mode 100644 index 00000000..5a4af136 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/invertBinaryTree.js @@ -0,0 +1,26 @@ + +//! O(n) time | O(n) space +function invertBinaryTree(tree) { + const queue = [tree]; + + while(queue.length) { + const current = queue.shift(); + + if(current == null) continue; + + swapLeftAndRight(current); + queue.push(current.left); + queue.push(current.right); + } +} +//! O(n) time | O(n) space +function invertBinaryTree(tree) { + if(!tree) return; + + swapLeftAndRight(tree); + invertBinaryTree(tree.left); + invertBinaryTree(tree.right); +} +function swapLeftAndRight(tree){ + [tree.left, tree.right] = [tree.left, tree.right]; +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/iterativeInOrderTraversal.js b/Javascript-DSA/BinaryTrees/AlgoExpert/iterativeInOrderTraversal.js new file mode 100644 index 00000000..1d2aa3cd --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/iterativeInOrderTraversal.js @@ -0,0 +1,25 @@ +//! O(n) time | O(1) space + +function iterativeInOrderTraversal(tree, callback) { + let previousNode = null; + let currentNode = tree; + + while(currentNode) { + let nextNode; + if(!previousNode || previousNode == currentNode.parent) { + if(currentNode.left) { + nextNode = currentNode.left; + } else { + callback(currentNode); + nextNode = currentNode.right ? currentNode.right : currentNode.parent; + } + } else if(previousNode == currentNode.left) { + callback(currentNode); + nextNode = currentNode.right ? currentNode.right : currentNode.parent; + } else { + nextNode = currentNode.parent; + } + previousNode = currentNode; + currentNode = nextNode; + } +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/levelOrderLevelWise.js b/Javascript-DSA/BinaryTrees/AlgoExpert/levelOrderLevelWise.js new file mode 100644 index 00000000..c52bacb6 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/levelOrderLevelWise.js @@ -0,0 +1,63 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + + +function levelOrderLevelWise(root) { + + + +} +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + + + diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/maxPathSum.js b/Javascript-DSA/BinaryTrees/AlgoExpert/maxPathSum.js new file mode 100644 index 00000000..c28b1a39 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/maxPathSum.js @@ -0,0 +1,22 @@ +//! O(n) time | O(logn) space + +//! Facebook +function maxPathSum(tree) { + const [_, maxSum] = findMaxSum(tree); + return maxSum; +} + +function findMaxSum(tree) { + if(!tree) return [-Infinity, -Infinity]; + + const [leftMaxSumAsBranch, leftMaxPathSum] = findMaxSum(tree.left); + const [rightMaxSumAsBranch, rightMaxPathSum] = findMaxSum(tree.right); + const maxChildSumAsBranch = Math.max(leftMaxSumAsBranch, rightMaxSumAsBranch); + + const {value} = tree.value; + const maxSumAsBranch = Math.max(maxChildSumAsBranch + value, value); + const maxSumAsRootNode = Math.max(leftMaxSumAsBranch + value + rightMaxSumAsBranch, maxSumAsBranch); + const maxPathSum = Math.max(leftMaxPathSum, rightMaxPathSum, maxSumAsRootNode); + + return [maxChildSumAsBranch, maxPathSum]; +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/nodeDepths.js b/Javascript-DSA/BinaryTrees/AlgoExpert/nodeDepths.js new file mode 100644 index 00000000..86943a62 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/nodeDepths.js @@ -0,0 +1,36 @@ +//! O(n) time | O(d) space +function nodeDepths(root, depth = 0) { + + if(root === null) return 0; + + return depth + nodeDepths(root.left, depth + 1) + nodeDepths(root.right, depth + 1); +} + +//! O(n) time | O(d) space +function nodeDepths(root) { + + let sumOfDepths = 0; + + const stack = [{node: root, depth: 0}]; + + while(stack.length > 0) { + const {node, depth} = stack.pop(); + if(node === null) continue; + + sumOfDepths += depth; + + stack.push({node: node.left, depth: depth + 1}); + stack.push( {node: node.right, depth: depth + 1}); + } + return sumOfDepths; +} + + +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/rightSiblingTree.js b/Javascript-DSA/BinaryTrees/AlgoExpert/rightSiblingTree.js new file mode 100644 index 00000000..a3b2cab1 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/rightSiblingTree.js @@ -0,0 +1,32 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +//! O(n) time | O(d) space where d is depth. +function rightSiblingTree(root) { + mutate(root, null, null); + return root; +} + +function mutate(node, parent, isLeftChild) { + if(!node) return; + + const left = node.left; + const right = node.right; + + mutate(left, parent, true); + + if(!parent) node.right = null; + else if(isLeftChild) node.right = parent.right; + else { + if(!parent.right) node.right = null; + else node.right = parent.right.left; + } + + mutate(right, parent, false); +} + diff --git a/Javascript-DSA/BinaryTrees/AlgoExpert/tempCodeRunnerFile.js b/Javascript-DSA/BinaryTrees/AlgoExpert/tempCodeRunnerFile.js new file mode 100644 index 00000000..52cd99bf --- /dev/null +++ b/Javascript-DSA/BinaryTrees/AlgoExpert/tempCodeRunnerFile.js @@ -0,0 +1,6 @@ +root.left.left = new Node(4); +root.left.right = new Node(5); +root.left.left.left = new Node(8); +root.left.left.right = new Node(9); +root.right.left = new Node(6); +root.right.right = new Node(7); \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/breadthFirstSearch.js b/Javascript-DSA/BinaryTrees/breadthFirstSearch.js new file mode 100644 index 00000000..cdad14dd --- /dev/null +++ b/Javascript-DSA/BinaryTrees/breadthFirstSearch.js @@ -0,0 +1,62 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } +} + +function levelOrderTraversal(root) { + let queue = new Queue(); + queue.enqueue(root); + + while(!queue.isEmpty()) { + let current = queue.dequeue(); + console.log(current.data); + + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.right = new Node(50); +root.right.left = new Node(60); +root.right.right = new Node(70); + +levelOrderTraversal(root); \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/checkMirror.js b/Javascript-DSA/BinaryTrees/checkMirror.js new file mode 100644 index 00000000..faebca69 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/checkMirror.js @@ -0,0 +1,29 @@ +//!12/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +function isMirror(a, b) { + if(a == null && b == null) return true; + if(a == null || b == null) return false; + + + return a.data == b.data && a.left == b.left && a.right == b.left; + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +console.log(isMirror(root, root)); \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/checkbinaryTreeIsBST.js b/Javascript-DSA/BinaryTrees/checkbinaryTreeIsBST.js new file mode 100644 index 00000000..d478ee8c --- /dev/null +++ b/Javascript-DSA/BinaryTrees/checkbinaryTreeIsBST.js @@ -0,0 +1,23 @@ +//! 15/02/2022 + +function isBST(root) { + if(root == null) { + return {max: Number.MIN_SAFE_INTEGER, min: Number.MAX_SAFE_INTEGER, isBst: true} + } + + let left = isBST(root.left); + let right = isBST(root.right); + if(left.isBst == true && right.isBst == true && root.data > left.max && root.data < right.min) { + return { + max: Math.max(left.max, right.max, root.data), + min: Math.min(left.min, right.min, root.data), + isBst: true + } + } else { + return { + max: Math.max(left.max, right.max, root.data), + min: Math.min(left.min, right.min, root.data), + isBst: false + } + } +} \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/constructBinary.js b/Javascript-DSA/BinaryTrees/constructBinary.js new file mode 100644 index 00000000..78db76c8 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/constructBinary.js @@ -0,0 +1,90 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear] = element; + this.rear++; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front]; + this.front++; + return temp; + } else { + return undefined; + } + } +} + +class node { + constructor(d) { + this.data = d; + this.left = null; + this.right = null; + } +} + +function levelOrderLevelWise(root) { + let qu = new Queue(); + let null_node = new node(null); + qu.enqueue(root); + qu.enqueue(null_node); + let result = ""; + while(!qu.isEmpty()) { + let curr = qu.dequeue(); + if(curr.data == null) { + // this is the end of the last level; + if(!qu.isEmpty()) { + qu.enqueue(new node(null)); + result += "\n"; + } + } else { + result += (curr.data + " "); + } + if(curr.left != null) { + qu.enqueue(curr.left); + } + if(curr.right != null) { + qu.enqueue(curr.right); + } + } + console.log(result); +} + +//! 15/02/2022 + +let preorderIndex = 0; +function search(inorder, l, r, data) { + for(let i = l; i <= r; i++) { + if(inorder[i] == data) return i; + } +} + +function buildTree(preorder, inorder, l, r) { + if(l > r) return null; + let newNode = new node(preorder[preorderIndex]); + preorderIndex++; + let inorderIndex = search(inorder, l, r, newNode.data); + newNode.left = buildTree(preorder, inorder, l, inorderIndex-1); + newNode.right = buildTree(preorder, inorder, inorderIndex+1, r); + return newNode; +} + +let pre = [3,9,20,15,7]; +let ino = [9,3,15,20,7]; + +let treenode = buildTree(pre, ino, 0, pre.length-1); +levelOrderLevelWise(treenode); diff --git a/Javascript-DSA/BinaryTrees/dummy.js b/Javascript-DSA/BinaryTrees/dummy.js new file mode 100644 index 00000000..7a8df829 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/dummy.js @@ -0,0 +1,60 @@ +class BinaryTree { + + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } + +} + + +function branchSums(root) { + + let sums = []; + + calculateBranchSums(root, 0, sums); + + return sums; +} + +function calculateBranchSums(node, runningSum, sums) { + + if(!node) return; + + const newRunningSum = runningSum + node.value; + + if(!node.left && !node.right) { + sums.push(newRunningSum); + return; + + } + + calculateBranchSums(node.left, newRunningSum, sums); + node.left = sums.pop(); + calculateBranchSums(node.right, newRunningSum, sums); + node.right = sums.pop(); + + +} + + + +const root = new BinaryTree(1); + +root.left = new BinaryTree(2); +root.right = new BinaryTree(3); + +root.left.left = new BinaryTree(4); +root.left.right = new BinaryTree(5); + +root.left.right.left = new BinaryTree(10); + +root.left.left.left = new BinaryTree(8); +root.left.left.right = new BinaryTree(9); + +root.right.left = new BinaryTree(6); +root.right.right = new BinaryTree(7); + + +console.log(branchSums(root)); \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/findHeight.js b/Javascript-DSA/BinaryTrees/findHeight.js new file mode 100644 index 00000000..6948b419 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/findHeight.js @@ -0,0 +1,30 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +function height(root) { + // if(root.left == null && root.right == null) return 0; + + if(root == null) return -1; + + let leftHeight = height(root.left); + let rightHeight = height(root.right); + return Math.max(leftHeight, rightHeight) + 1; +} + + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +console.log(height(root)); diff --git a/Javascript-DSA/BinaryTrees/findMaxElement.js b/Javascript-DSA/BinaryTrees/findMaxElement.js new file mode 100644 index 00000000..f3b24c24 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/findMaxElement.js @@ -0,0 +1,28 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +function findMaxElement(root) { + if(root == null) return Number.MIN_SAFE_INTEGER; + + let leftMaxElement = findMaxElement(root.left); + let rightMaxElement = findMaxElement(root.right); + + return Math.max(leftMaxElement, rightMaxElement, root.data); +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +console.log(findMaxElement(root)); diff --git a/Javascript-DSA/BinaryTrees/findPath.js b/Javascript-DSA/BinaryTrees/findPath.js new file mode 100644 index 00000000..345a18eb --- /dev/null +++ b/Javascript-DSA/BinaryTrees/findPath.js @@ -0,0 +1,59 @@ +//! 15/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +let preorderIndex = 0; +function search(inorder, l, r, data) { + for(let i = l; i <= r; i++) { + if(inorder[i] == data) return i; + } +} +function buildTree(preorder, inorder, l, r) { + if(l > r) return null; + let newNode = new Node(preorder[preorderIndex]); + preorderIndex++; + let inorderIndex = search(inorder, l, r, newNode.data); + newNode.left = buildTree(preorder, inorder, l, inorderIndex-1); + newNode.right = buildTree(preorder, inorder, inorderIndex+1, r); + return newNode; +} + + +function findPath(root, target, array) { + if(root == null) return false; + array.push(root.data); + if(root.data == target) return true; + if(findPath(root.left, target, array) || findPath(root.right, target, array)) + return true; + + array.pop(); + return false; + +} + +let pre = [3,9,20,15,7]; +let ino = [9,3,15,20,7]; + +let treeNode = buildTree(pre, ino, 0, pre.length-1); +// levelOrderLevelWise(treenode); + +let array = []; +findPath(treeNode, 15, array); +console.log(array); + +const root = new Node(1); +root.left = new Node(2); +root.right = new Node(3); +root.left.left = new Node(4); +root.left.right = new Node(5); +root.left.left.left = new Node(8); +root.left.left.right = new Node(9); +root.right.left = new Node(6); +root.right.right = new Node(7); diff --git a/Javascript-DSA/BinaryTrees/levelOrderLevelWise.js b/Javascript-DSA/BinaryTrees/levelOrderLevelWise.js new file mode 100644 index 00000000..2c766337 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/levelOrderLevelWise.js @@ -0,0 +1,88 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + + +function levelOrderLevelWise(root) { + + let queue = new Queue(); + let null_node = new Node(null); + queue.enqueue(root); + queue.enqueue(null_node); + let result = ""; + while(!queue.isEmpty()) { + let current = queue.dequeue(); + if(current.data == null) { + if(!queue.isEmpty()) { + queue.enqueue(new Node(null)); + result += "\n"; + } + } else { + result += (current.data + " "); + } + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } + console.log(result); + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +levelOrderLevelWise(root); + + + diff --git a/Javascript-DSA/BinaryTrees/lowestCommonAncestor.js b/Javascript-DSA/BinaryTrees/lowestCommonAncestor.js new file mode 100644 index 00000000..4bed8079 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/lowestCommonAncestor.js @@ -0,0 +1,110 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear] = element; + this.rear++; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front]; + this.front++; + return temp; + } else { + return undefined; + } + } +} + +class node { + constructor(d) { + this.data = d; + this.left = null; + this.right = null; + } +} + +function levelOrderLevelWise(root) { + let qu = new Queue(); + let null_node = new node(null); + qu.enqueue(root); + qu.enqueue(null_node); + let result = ""; + while(!qu.isEmpty()) { + let curr = qu.dequeue(); + if(curr.data == null) { + // this is the end of the last level; + if(!qu.isEmpty()) { + qu.enqueue(new node(null)); + result += "\n"; + } + } else { + result += (curr.data + " "); + } + if(curr.left != null) { + qu.enqueue(curr.left); + } + if(curr.right != null) { + qu.enqueue(curr.right); + } + } + console.log(result); +} + +//! 15/02/2022 + +let preorderIndex = 0; +function search(inorder, l, r, data) { + for(let i = l; i <= r; i++) { + if(inorder[i] == data) return i; + } +} + +function buildTree(preorder, inorder, l, r) { + if(l > r) return null; + let newNode = new node(preorder[preorderIndex]); + preorderIndex++; + let inorderIndex = search(inorder, l, r, newNode.data); + newNode.left = buildTree(preorder, inorder, l, inorderIndex-1); + newNode.right = buildTree(preorder, inorder, inorderIndex+1, r); + return newNode; +} + +let lca_ans = null; +function lca(root, p, q) { + if(root == null) return 0; + let left = lca(root.left, p, q); + let right = lca(root.right, p, q); + let curr = (root.data == p || root.data == q); + + if(curr + left + right >= 2){ + lca_ans = root.data; + } + return curr + left + right; +} + +let pre = [3,9,20,15,7]; +let ino = [9,3,15,20,7]; + +let treenode = buildTree(pre, ino, 0, pre.length-1); +// levelOrderLevelWise(treenode); + +lca(treenode, 9, 15); +console.log("lca-", lca_ans); + + + + diff --git a/Javascript-DSA/BinaryTrees/nodeStructure.js b/Javascript-DSA/BinaryTrees/nodeStructure.js new file mode 100644 index 00000000..ba67d748 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/nodeStructure.js @@ -0,0 +1,56 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +function findPath(root) { + + let leftPath = findLeftPath(root); + let rightPath = findRightPath(root); + + let result = []; + + result.push(leftPath); + result.push(rightPath); + + return result; + + } + +function findLeftPath(root) { + + findSum(root, 0); + +} + +function findRightPath(root) { + +if(root.left == null && root.right == null) return root.data; +return root.data + findRightPath(root.right); + +} + +function findSum(root, sum ) { + if(root.left == null && root.right == null) return; + +} + + + +const root = new Node(1); +root.left = new Node(2); +root.right = new Node(3); +root.left.left = new Node(4); +root.left.right = new Node(5); +root.left.left.left = new Node(8); +root.left.left.right = new Node(9); +root.right.left = new Node(6); +root.right.right = new Node(7); + + + diff --git a/Javascript-DSA/BinaryTrees/printRightView.js b/Javascript-DSA/BinaryTrees/printRightView.js new file mode 100644 index 00000000..8ae09ce0 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/printRightView.js @@ -0,0 +1,132 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +function printRightViewAlgo1(root) { + + let queue = new Queue(); + let null_node = new Node(null); + queue.enqueue(root); + queue.enqueue(null_node); + let result = []; + while(!queue.isEmpty()) { + let current = queue.dequeue(); + if(current.data == null) { + console.log(result[result.length - 1]); + if(!queue.isEmpty()) { + queue.enqueue(new Node(null)); + result = []; + } + } else { + result.push(current.data); + } + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } +} + +function printRightViewAlgo2(root) { + //! removed result array + let queue = new Queue(); + let null_node = new Node(null); + queue.enqueue(root); + queue.enqueue(null_node); + let last_element = undefined; + + while(!queue.isEmpty()) { + let current = queue.dequeue(); + if(current.data == null) { + console.log(last_element); + if(!queue.isEmpty()) { + queue.enqueue(new Node(null)); + } + } else { + last_element = current.data; + } + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } +} + +let maxLevelVisited = -1; +function printRightViewAlgo3(root, current) { + if(root == null) return; + + if(current > maxLevelVisited) { + console.log(root.data); + maxLevelVisited = current; + } + + printRightViewAlgo3(root.right, current + 1); + printRightViewAlgo3(root.left, current + 1); + + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +// printRightViewAlgo1(root); + +// printRightViewAlgo2(root); + +printRightViewAlgo3(root, 0); + + + diff --git a/Javascript-DSA/BinaryTrees/tempCodeRunnerFile.js b/Javascript-DSA/BinaryTrees/tempCodeRunnerFile.js new file mode 100644 index 00000000..6a54eb94 --- /dev/null +++ b/Javascript-DSA/BinaryTrees/tempCodeRunnerFile.js @@ -0,0 +1 @@ +let temp = this.heap[idx]; \ No newline at end of file diff --git a/Javascript-DSA/BinaryTrees/treeTraversal.js b/Javascript-DSA/BinaryTrees/treeTraversal.js new file mode 100644 index 00000000..0a0f39ce --- /dev/null +++ b/Javascript-DSA/BinaryTrees/treeTraversal.js @@ -0,0 +1,42 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + +function preOrder(root) { + if(root == null) return; + console.log(root.data); + preOrder(root.left); + preOrder(root.right); +} + +function inOrder(root) { + if (root == null) return; + inOrder(root.left); + console.log(root.data); + inOrder(root.right); +} + +function postOrder(root) { + if(root == null) return; + postOrder(root.left); + postOrder(root.right); + console.log(root.data); +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); +preOrder(root); +console.log(">>>>>>>>>"); +inOrder(root); +console.log(">>>>>>>>>"); +postOrder(root) \ No newline at end of file diff --git a/Javascript-DSA/DAC/continousMaxSubArraySum.cpp b/Javascript-DSA/DAC/continousMaxSubArraySum.cpp new file mode 100644 index 00000000..b517f234 --- /dev/null +++ b/Javascript-DSA/DAC/continousMaxSubArraySum.cpp @@ -0,0 +1,69 @@ +#include + +using namespace std; + +int max(int leftSum, int rightSum, int crossSum) { + if (leftSum > rightSum && leftSum > crossSum) { + return leftSum; + } else if (rightSum > leftSum && rightSum > crossSum) { + return rightSum; + } + else if (crossSum > leftSum && crossSum > rightSum) { + return crossSum; + } +} + +void printArr(int arr[], int i, int j) { + for (int k = i; k <= j; k++) { + cout << arr[k] << " "; + } +} + +int findCrossSum(int arr[], int midLeft, int p, int midRight, int q) +{ + int leftBestSum = 0, leftTotalSum = 0, rightBestSum = 0, rightTotalSum = 0; + int leftBestSumPosition = -1, rightBestSumPosition = -1; + + for (int i = midLeft; i >= 0; i--) { + leftTotalSum = leftTotalSum + arr[i]; + if (leftTotalSum > leftBestSum) { + leftBestSum = leftTotalSum; + leftBestSumPosition = i; + } + } + + for (int i = midRight; i < q; i++) { + rightTotalSum = rightTotalSum + arr[i]; + if (rightTotalSum > rightBestSum) { + rightBestSum = rightTotalSum; + rightBestSumPosition = i; + } + } + printArr(arr, leftBestSumPosition, rightBestSumPosition); + +} +int continousMaxSubArraySum(int arr[], int p, int q) +{ + if ( p == q) { + return arr[p]; + } else { + int mid = (p + q) / 2; + int leftSum = continousMaxSubArraySum(arr, p, mid); + int rightSum = continousMaxSubArraySum(arr, mid + 1, q); + int crossSum = findCrossSum(arr, mid, p, mid + 1, q); + return max(leftSum, rightSum, crossSum); + } +} + +int main () { + int arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; + + int p = 0; + + int q = sizeof(arr)/sizeof(arr[0]); + + // cout << "\nMAX SUM " << continousMaxSubArraySum(arr, p, q); + continousMaxSubArraySum(arr, p, q); + + return 0; +} \ No newline at end of file diff --git a/Javascript-DSA/DAC/continousMaxSubArraySum.exe b/Javascript-DSA/DAC/continousMaxSubArraySum.exe new file mode 100644 index 00000000..8e629d9a Binary files /dev/null and b/Javascript-DSA/DAC/continousMaxSubArraySum.exe differ diff --git a/Javascript-DSA/DAC/dummy.cpp b/Javascript-DSA/DAC/dummy.cpp new file mode 100644 index 00000000..22c6f85c --- /dev/null +++ b/Javascript-DSA/DAC/dummy.cpp @@ -0,0 +1,66 @@ +/* C++ implementation of QuickSort */ +#include +using namespace std; + +// A utility function to swap two elements +void swap(int *a, int *b) +{ + int t = *a; + *a = *b; + *b = t; +} + +int partition(int arr[], int p, int q) +{ + int i = p; + int x = arr[p]; + for (int j = p + 1; j <= q; j++) + { + if (arr[j] <= x) + { + i++; + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + } + int temp = arr[p]; + arr[p] = arr[i]; + arr[i] = temp; + return i; +} + +void quickSort(int arr[], int low, int high) +{ + if (low == high) return; + { + /* pi is partitioning index, arr[p] is now + at right place */ + int pi = partition(arr, low, high); + + // Separately sort elements before + // partition and after partition + quickSort(arr, low, pi - 1); + quickSort(arr, pi + 1, high); + } +} + +/* Function to print an array */ +void printArray(int arr[], int size) +{ + int i; + for (i = 0; i < size; i++) + cout << arr[i] << " "; + cout << endl; +} + +// Driver Code +int main() +{ + int arr[] = {10, 7, 8, 9, 1, 5}; + int n = sizeof(arr) / sizeof(arr[0]); + quickSort(arr, 0, n - 1); + cout << "Sorted array: \n"; + printArray(arr, n); + return 0; +} diff --git a/Javascript-DSA/DAC/dummy.exe b/Javascript-DSA/DAC/dummy.exe new file mode 100644 index 00000000..f01cf20b Binary files /dev/null and b/Javascript-DSA/DAC/dummy.exe differ diff --git a/Javascript-DSA/DAC/mergeSort.cpp b/Javascript-DSA/DAC/mergeSort.cpp new file mode 100644 index 00000000..ccaacc67 --- /dev/null +++ b/Javascript-DSA/DAC/mergeSort.cpp @@ -0,0 +1,73 @@ +#include + +using namespace std; + +void merge(int arr[], int start, int mid, int end) +{ + int leftSubArraySize = mid - start + 1; + int rightSubArraySize = end - (mid + 1) + 1; + + int leftSubArray[leftSubArraySize]; + int rightSubArray[rightSubArraySize]; + + for (int i = 0; i < leftSubArraySize; i++) + { + leftSubArray[i] = arr[i + start]; + } + for (int i = 0; i < rightSubArraySize; i++) + { + rightSubArray[i] = arr[i + mid + 1]; + } + + int i = 0; + int j = 0; + int k = start; + + while ((i < leftSubArraySize) && (j < rightSubArraySize)) + { + if (leftSubArray[i] < rightSubArray[j]) + { + arr[k++] = leftSubArray[i++]; + } + else + { + arr[k++] = rightSubArray[j++]; + } + } + while (i < leftSubArraySize) + { + arr[k++] = leftSubArray[i++]; + } + while (j < rightSubArraySize) + { + arr[k++] = rightSubArray[j++]; + } +} +int mergeSort(int arr[], int i, int j) +{ + if (i == j) + return arr[i]; + + else + { + int mid = (i + j) / 2; + mergeSort(arr, i, mid); + mergeSort(arr, mid + 1, j); + merge(arr, i, mid, j); + } +} + +int main () { + + int arr[] = {50, 60, 70, 80, 10, 12, 13, 8, 3, 2, 1, 0}; + + int len = sizeof(arr) / sizeof(arr[0]); + + mergeSort(arr, 0, 12); + + for ( int i = 0; i < 12; i++ ) { + cout << arr[i] << " "; + } + + return 0; +} \ No newline at end of file diff --git a/Javascript-DSA/DAC/mergeSort.exe b/Javascript-DSA/DAC/mergeSort.exe new file mode 100644 index 00000000..259055bd Binary files /dev/null and b/Javascript-DSA/DAC/mergeSort.exe differ diff --git a/Javascript-DSA/DAC/numberOfInversions.cpp b/Javascript-DSA/DAC/numberOfInversions.cpp new file mode 100644 index 00000000..c50783d0 --- /dev/null +++ b/Javascript-DSA/DAC/numberOfInversions.cpp @@ -0,0 +1,69 @@ +#include "bits/stdc++.h" +using namespace std; + +int merge(int arr[], int start, int mid, int end) +{ + int inversions = 0; + int l = 0; + int len = sizeof(arr) / sizeof(arr[0]); + + int leftSubArraySize = mid - start + 1; + int rightSubArraySize = end - mid; + + int leftSubArray[leftSubArraySize]; + int rightSubArray[rightSubArraySize]; + + for (int i = 0; i < leftSubArraySize; i++) + { + leftSubArray[i] = arr[i + start + i]; + } + for (int i = 0; i < rightSubArraySize; i++) + { + rightSubArray[i] = arr[i + mid + i]; + } + + int i = 0; + int j = 0; + int k = start; + // int b[len]; + + while ((i < leftSubArraySize) && (j < rightSubArraySize)) + { + if (leftSubArray[i] < rightSubArray[j]) + { + arr[k++] = leftSubArray[i++]; + } + else + { + arr[k++] = rightSubArray[j++]; + inversions += leftSubArraySize - i; + } + } + + while (i < leftSubArraySize) + { + arr[k++] = leftSubArray[i++]; + } + while (j < rightSubArraySize) + { + arr[k++] = rightSubArray[j++]; + } + return inversions; +} +int mergeSort(int arr[], int i, int j) +{ + if (i == j) return 0; + int mid = (i + j) / 2; + int leftInversions = mergeSort(arr, i, mid); + int rightInversions = mergeSort(arr, mid + 1, j); + int mergedInversions = merge(arr, i, mid, j); + + return leftInversions + rightInversions + mergedInversions; +} +int main() +{ + + int arr[] ={50, 40, 20, 5, 19, 90, 23, 16}; + cout << mergeSort(arr, 0, 8); + return 0; +} diff --git a/Javascript-DSA/DAC/numberOfInversions.exe b/Javascript-DSA/DAC/numberOfInversions.exe new file mode 100644 index 00000000..51748bf3 Binary files /dev/null and b/Javascript-DSA/DAC/numberOfInversions.exe differ diff --git a/Javascript-DSA/DAC/quickSort.cpp b/Javascript-DSA/DAC/quickSort.cpp new file mode 100644 index 00000000..bd077ce6 --- /dev/null +++ b/Javascript-DSA/DAC/quickSort.cpp @@ -0,0 +1,66 @@ +#include +using namespace std; + +void printArr(int arr[], int len) { + for (int i = 0; i < len; i++) { + cout << arr[i] << " "; + } +} + +void swap(int *i, int *j) { + int temp = *i; + *i = *j; + *j = temp; +} + +int partition(int arr[], int p, int q) { + int i = p; + int x = arr[i]; // ! PIVOT + + for (int j = p + 1; j <= q; j++) { + if (arr[j] <= x) { + i++; + swap(&arr[i], &arr[j]); + } + } + swap(&arr[i], &arr[p]); + return i; +} + +int quickSort(int arr[], int p, int q) { + // if (p >= q) return; + // else { + // int m = partition(arr, p, q); + // quickSort(arr, p, m - 1); + // quickSort(arr, m + 1, q); + // } + + //! MODIFIED QUICK SORT + + while (p <= q) { + if (p == q) return arr[p]; + else { + int m = partition(arr, p, q); + if ( (m - p) < (q - m) ) { + quickSort(arr, p, m - 1); + p = m + 1; + } else { + quickSort(arr, m + 1, q); + q = m - 1; + } + } + } +} + +int main () { + + int arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + + int len = sizeof(arr)/ sizeof(arr[0]); + + quickSort(arr, 0, len - 1); + + printArr(arr, len); + + return 0; +} \ No newline at end of file diff --git a/Javascript-DSA/DAC/quickSort.exe b/Javascript-DSA/DAC/quickSort.exe new file mode 100644 index 00000000..1c654b80 Binary files /dev/null and b/Javascript-DSA/DAC/quickSort.exe differ diff --git a/Javascript-DSA/DAC/selectionProcedure.cpp b/Javascript-DSA/DAC/selectionProcedure.cpp new file mode 100644 index 00000000..0c8d8d3e --- /dev/null +++ b/Javascript-DSA/DAC/selectionProcedure.cpp @@ -0,0 +1,54 @@ +#include + +using namespace std; + +void swap(int *i, int *j) +{ + int temp = *i; + *i = *j; + *j = temp; +} +int partition(int arr[], int p, int q) +{ + int i = p; + int x = arr[i]; // ! PIVOT + + for (int j = p + 1; j <= q; j++) + { + if (arr[j] <= x) + { + i++; + swap(&arr[i], &arr[j]); + } + } + swap(&arr[i], &arr[p]); + return i; +} +int selectionProcedure(int arr[], int p, int q, int k) { + if (p == q) return arr[p]; + else + { + int m = partition(arr, p, q); + if (m == k) return arr[k]; + else { + if (k < m) + selectionProcedure(arr, p, m - 1, q); + else + { + selectionProcedure(arr, m + 1, q, k); + } + } + } +} + +int main () { + + int arr[] = { 50, 25, 85, 45, 30, 62, 88, 98, 110, 15, 29, 69 }; + + int q = sizeof(arr) / sizeof(arr[0]); + int p = 0; + int k = 4; + cout << selectionProcedure(arr, p, q, k); + + return 0; +} \ No newline at end of file diff --git a/Javascript-DSA/DAC/selectionProcedure.exe b/Javascript-DSA/DAC/selectionProcedure.exe new file mode 100644 index 00000000..6c831129 Binary files /dev/null and b/Javascript-DSA/DAC/selectionProcedure.exe differ diff --git a/Javascript-DSA/DAC/tempCodeRunnerFile.cpp b/Javascript-DSA/DAC/tempCodeRunnerFile.cpp new file mode 100644 index 00000000..0519ecba --- /dev/null +++ b/Javascript-DSA/DAC/tempCodeRunnerFile.cpp @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Javascript-DSA/FamousAlgorithms/.DS_Store b/Javascript-DSA/FamousAlgorithms/.DS_Store new file mode 100644 index 00000000..65dfc670 Binary files /dev/null and b/Javascript-DSA/FamousAlgorithms/.DS_Store differ diff --git a/Javascript-DSA/FamousAlgorithms/AlgoExpert/kadanesAlgorithm.js b/Javascript-DSA/FamousAlgorithms/AlgoExpert/kadanesAlgorithm.js new file mode 100644 index 00000000..ef37a97f --- /dev/null +++ b/Javascript-DSA/FamousAlgorithms/AlgoExpert/kadanesAlgorithm.js @@ -0,0 +1,21 @@ +//! https://leetcode.com/problems/maximum-subarray/submissions/ +//! https://www.algoexpert.io/questions/kadane's-algorithm + +console.time("runTime"); +function kadanesAlgorithm(array) { + let maxEndingHere = array[0]; + let maxSoFar = array[0]; + + for(let i = 1; i < array.length; i++) { + const num = array[i]; + maxEndingHere = Math.max(maxEndingHere + num, num); + maxSoFar = Math.max(maxSoFar, maxEndingHere); + } + return maxSoFar; +} + +const array = [3, 5, -9, 1, 3, -2, 3, 4, 7, 2, -9, 6, 3, 1, -5, 4]; + +console.log(kadanesAlgorithm(array)); + +console.timeEnd("runTime"); \ No newline at end of file diff --git a/Javascript-DSA/FamousAlgorithms/StriverSheet/kadanesAlgorithm.js b/Javascript-DSA/FamousAlgorithms/StriverSheet/kadanesAlgorithm.js new file mode 100644 index 00000000..5443d5ce --- /dev/null +++ b/Javascript-DSA/FamousAlgorithms/StriverSheet/kadanesAlgorithm.js @@ -0,0 +1,20 @@ +//! https://leetcode.com/problems/maximum-subarray/submissions/ + +console.time("runTime"); +function kadanesAlgorithm(array) { + let maxEndingHere = array[0]; + let maxSoFar = array[0]; + + for(let i = 1; i < array.length; i++) { + const num = array[i]; + maxEndingHere = Math.max(maxEndingHere + num, num); + maxSoFar = Math.max(maxSoFar, maxEndingHere); + } + return maxSoFar; +} + +const array = [3, 5, -9, 1, 3, -2, 3, 4, 7, 2, -9, 6, 3, 1, -5, 4]; + +console.log(kadanesAlgorithm(array)); + +console.timeEnd("runTime"); \ No newline at end of file diff --git a/Javascript-DSA/Hashing/.DS_Store b/Javascript-DSA/Hashing/.DS_Store new file mode 100644 index 00000000..c3d99512 Binary files /dev/null and b/Javascript-DSA/Hashing/.DS_Store differ diff --git a/Javascript-DSA/Hashing/AlgoExpert/groupAnagrams.js b/Javascript-DSA/Hashing/AlgoExpert/groupAnagrams.js new file mode 100644 index 00000000..b83c3d3b --- /dev/null +++ b/Javascript-DSA/Hashing/AlgoExpert/groupAnagrams.js @@ -0,0 +1,17 @@ +function group(array) { //! Time O(nklogk) klogk --> sorting time for every string + let hash_map = {}; + for(let i = 0; i < array.length; i++) { + let sorted_perm = array[i].split("").sort().join(""); + if(hash_map[sorted_perm] == undefined) { + console.log(hash_map); + hash_map[sorted_perm] = [array[i]]; + console.log(hash_map); + } else { + hash_map[sorted_perm].push(array[i]); + } + } + // return hash_map; + return Object.values(hash_map); +} + +console.log((group(["bat", "ate", "eat", "tan", "nat", "tea"]))); \ No newline at end of file diff --git a/Javascript-DSA/Hashing/AlgoExpert/hashtable_implimentation.js b/Javascript-DSA/Hashing/AlgoExpert/hashtable_implimentation.js new file mode 100644 index 00000000..28348bc3 --- /dev/null +++ b/Javascript-DSA/Hashing/AlgoExpert/hashtable_implimentation.js @@ -0,0 +1,91 @@ +class HashTable { + constructor() { + this.loadFactor = 0; + this.MAX_LOAD_FACTOR = 0.5; + this.sizeOfHashTable = 2; + this.noOfElements = 0; + this.hash_table = new Array(this.sizeOfHashTable); + } + hash(key) { + let result = 0; + let prime = 5381; + for(let i = 0; i < key.length; i++) { + result = (result + (key.charCodeAt(i)*prime)%this.sizeOfHashTable)%this.sizeOfHashTable; + prime *= 5381; + } + return result; + } + rehash() { + console.log("rehashing..."); + this.sizeOfHashTable *= 2; + let old_hash_table = this.hash_table; + this.hash_table = new Array(this.sizeOfHashTable); + this.noOfElements = 0; + for(let i = 0; i < old_hash_table.length; i++) { + if(old_hash_table[i] == undefined) continue; + for(let j = 0; j < old_hash_table[i].length; j++) { + this.insert(old_hash_table[i][j][0], old_hash_table[i][j][1]); + } + } + } + insert(key, value) { + const hash_table_index = this.hash(key); + if(this.hash_table[hash_table_index] == undefined) { + this.hash_table[hash_table_index] = []; + this.hash_table[hash_table_index].push([key, value]); + } else { + for(let i = 0; i < this.hash_table[hash_table_index].length; i++) { + if(this.hash_table[hash_table_index][i][0] == key) { + console.log(this.hash_table); + this.hash_table[hash_table_index][i][1] = value; + console.log("-------------------"); + console.log(this.hash_table); + return; + } + } + this.hash_table[hash_table_index].push([key, value]); + } + this.noOfElements += 1; + this.loadFactor = this.noOfElements / this.sizeOfHashTable; + if(this.loadFactor > this.MAX_LOAD_FACTOR) { + this.rehash(); + } + } + search(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return undefined; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + console.log(hash_table[hi][i][0]); + return this.hash_table[hi][i][1]; + } + } + } + printHashTable() { + return this.hash_table; + } + remove(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return -1; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + this.noOfElements--; + return { + key: this.hash_table[hi][i].pop(), + value: this.hash_table[hi][i].pop() + } + } + } + } +} +let ht = new HashTable(); +ht.insert("a", "1"); +ht.insert("b", "2"); +ht.insert("c", "3"); +ht.insert("d", "4"); +ht.insert("a", "5"); +// console.log(ht.search("a")); + +// console.log(ht.remove("d")); +console.log(ht.printHashTable()); + diff --git a/Javascript-DSA/Hashing/AlgoExpert/longest_substring_without_duplicates.js b/Javascript-DSA/Hashing/AlgoExpert/longest_substring_without_duplicates.js new file mode 100644 index 00000000..7369eab3 --- /dev/null +++ b/Javascript-DSA/Hashing/AlgoExpert/longest_substring_without_duplicates.js @@ -0,0 +1,17 @@ +//! O(n) time | O(min(n, a)) space +function longestSubstringWithoutDuplication(string) { + const lastSeen = {}; + let longest = [0, 1]; + let startIdx = 0; + for(let i = 0; i < string.length; i++) { + const char = string[i]; + if(char in lastSeen) { + startIdx = Math.max(startIdx, lastSeen[char] + 1); + } if(longest[1] - longest[0] < i + 1 - startIdx){ + longest = [startIdx, i+1]; + } + lastSeen[char] = i; + } + return string.slice(longest[0], longest[1]); + +} diff --git a/Javascript-DSA/Hashing/AlgoExpert/maxFrequencyCharacter.js b/Javascript-DSA/Hashing/AlgoExpert/maxFrequencyCharacter.js new file mode 100644 index 00000000..8fb4f99d --- /dev/null +++ b/Javascript-DSA/Hashing/AlgoExpert/maxFrequencyCharacter.js @@ -0,0 +1,18 @@ +function maxFreqChar(str) { + let hm = {}; + for(let i = 0; i < str.length; i++) { + if(hm[str[i]] == undefined) hm[str[i]] = 1; + else hm[str[i]] += 1; + } + let maxFreq = 0; + let ans = undefined; + for(const [key, value] of Object.entries(hm)) { + if(maxFreq < value) { + ans = value; + maxFreq = value; + } + } + return ans; +} + +console.log(maxFreqChar("aaaaaabc")); \ No newline at end of file diff --git a/Javascript-DSA/Hashing/AlgoExpert/tempCodeRunnerFile.js b/Javascript-DSA/Hashing/AlgoExpert/tempCodeRunnerFile.js new file mode 100644 index 00000000..d4351c98 --- /dev/null +++ b/Javascript-DSA/Hashing/AlgoExpert/tempCodeRunnerFile.js @@ -0,0 +1 @@ +ht \ No newline at end of file diff --git a/Javascript-DSA/Hashing/groupAnagrams.js b/Javascript-DSA/Hashing/groupAnagrams.js new file mode 100644 index 00000000..b83c3d3b --- /dev/null +++ b/Javascript-DSA/Hashing/groupAnagrams.js @@ -0,0 +1,17 @@ +function group(array) { //! Time O(nklogk) klogk --> sorting time for every string + let hash_map = {}; + for(let i = 0; i < array.length; i++) { + let sorted_perm = array[i].split("").sort().join(""); + if(hash_map[sorted_perm] == undefined) { + console.log(hash_map); + hash_map[sorted_perm] = [array[i]]; + console.log(hash_map); + } else { + hash_map[sorted_perm].push(array[i]); + } + } + // return hash_map; + return Object.values(hash_map); +} + +console.log((group(["bat", "ate", "eat", "tan", "nat", "tea"]))); \ No newline at end of file diff --git a/Javascript-DSA/Hashing/hashtable_implimentation.js b/Javascript-DSA/Hashing/hashtable_implimentation.js new file mode 100644 index 00000000..28348bc3 --- /dev/null +++ b/Javascript-DSA/Hashing/hashtable_implimentation.js @@ -0,0 +1,91 @@ +class HashTable { + constructor() { + this.loadFactor = 0; + this.MAX_LOAD_FACTOR = 0.5; + this.sizeOfHashTable = 2; + this.noOfElements = 0; + this.hash_table = new Array(this.sizeOfHashTable); + } + hash(key) { + let result = 0; + let prime = 5381; + for(let i = 0; i < key.length; i++) { + result = (result + (key.charCodeAt(i)*prime)%this.sizeOfHashTable)%this.sizeOfHashTable; + prime *= 5381; + } + return result; + } + rehash() { + console.log("rehashing..."); + this.sizeOfHashTable *= 2; + let old_hash_table = this.hash_table; + this.hash_table = new Array(this.sizeOfHashTable); + this.noOfElements = 0; + for(let i = 0; i < old_hash_table.length; i++) { + if(old_hash_table[i] == undefined) continue; + for(let j = 0; j < old_hash_table[i].length; j++) { + this.insert(old_hash_table[i][j][0], old_hash_table[i][j][1]); + } + } + } + insert(key, value) { + const hash_table_index = this.hash(key); + if(this.hash_table[hash_table_index] == undefined) { + this.hash_table[hash_table_index] = []; + this.hash_table[hash_table_index].push([key, value]); + } else { + for(let i = 0; i < this.hash_table[hash_table_index].length; i++) { + if(this.hash_table[hash_table_index][i][0] == key) { + console.log(this.hash_table); + this.hash_table[hash_table_index][i][1] = value; + console.log("-------------------"); + console.log(this.hash_table); + return; + } + } + this.hash_table[hash_table_index].push([key, value]); + } + this.noOfElements += 1; + this.loadFactor = this.noOfElements / this.sizeOfHashTable; + if(this.loadFactor > this.MAX_LOAD_FACTOR) { + this.rehash(); + } + } + search(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return undefined; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + console.log(hash_table[hi][i][0]); + return this.hash_table[hi][i][1]; + } + } + } + printHashTable() { + return this.hash_table; + } + remove(key) { + const hi = this.hash(key); + if(this.hash_table[hi] == undefined) return -1; + for(let i = 0; i < this.hash_table[hi].length; i++) { + if(this.hash_table[hi][i][0] == key) { + this.noOfElements--; + return { + key: this.hash_table[hi][i].pop(), + value: this.hash_table[hi][i].pop() + } + } + } + } +} +let ht = new HashTable(); +ht.insert("a", "1"); +ht.insert("b", "2"); +ht.insert("c", "3"); +ht.insert("d", "4"); +ht.insert("a", "5"); +// console.log(ht.search("a")); + +// console.log(ht.remove("d")); +console.log(ht.printHashTable()); + diff --git a/Javascript-DSA/Hashing/longest_substring_without_duplicates.js b/Javascript-DSA/Hashing/longest_substring_without_duplicates.js new file mode 100644 index 00000000..7369eab3 --- /dev/null +++ b/Javascript-DSA/Hashing/longest_substring_without_duplicates.js @@ -0,0 +1,17 @@ +//! O(n) time | O(min(n, a)) space +function longestSubstringWithoutDuplication(string) { + const lastSeen = {}; + let longest = [0, 1]; + let startIdx = 0; + for(let i = 0; i < string.length; i++) { + const char = string[i]; + if(char in lastSeen) { + startIdx = Math.max(startIdx, lastSeen[char] + 1); + } if(longest[1] - longest[0] < i + 1 - startIdx){ + longest = [startIdx, i+1]; + } + lastSeen[char] = i; + } + return string.slice(longest[0], longest[1]); + +} diff --git a/Javascript-DSA/Hashing/maxFrequencyCharacter.js b/Javascript-DSA/Hashing/maxFrequencyCharacter.js new file mode 100644 index 00000000..8fb4f99d --- /dev/null +++ b/Javascript-DSA/Hashing/maxFrequencyCharacter.js @@ -0,0 +1,18 @@ +function maxFreqChar(str) { + let hm = {}; + for(let i = 0; i < str.length; i++) { + if(hm[str[i]] == undefined) hm[str[i]] = 1; + else hm[str[i]] += 1; + } + let maxFreq = 0; + let ans = undefined; + for(const [key, value] of Object.entries(hm)) { + if(maxFreq < value) { + ans = value; + maxFreq = value; + } + } + return ans; +} + +console.log(maxFreqChar("aaaaaabc")); \ No newline at end of file diff --git a/Javascript-DSA/Hashing/minimumWindowSubstring.js b/Javascript-DSA/Hashing/minimumWindowSubstring.js new file mode 100644 index 00000000..ea463340 --- /dev/null +++ b/Javascript-DSA/Hashing/minimumWindowSubstring.js @@ -0,0 +1,18 @@ +//! https://leetcode.com/problems/minimum-window-substring/ +//! https://www.algoexpert.io/questions/Smallest%20Substring%20Containing + +function minWindow(s, t) { + let freq = new Array(256).fill(0); + let ans = Number.MAX_SAFE_INTEGER; + for(let i = 0; i < t.length; i++) { + freq[t[i].charCodeAt(0)]++; + } + let i = 0, j = 0; + let t_length = t.length; + while(j < s.length) { + freq[s[j].charCodeAt(0)]--; + + } +} + + diff --git a/Javascript-DSA/Hashing/tempCodeRunnerFile.js b/Javascript-DSA/Hashing/tempCodeRunnerFile.js new file mode 100644 index 00000000..d4351c98 --- /dev/null +++ b/Javascript-DSA/Hashing/tempCodeRunnerFile.js @@ -0,0 +1 @@ +ht \ No newline at end of file diff --git a/Javascript-DSA/Heaps/.DS_Store b/Javascript-DSA/Heaps/.DS_Store new file mode 100644 index 00000000..c3d99512 Binary files /dev/null and b/Javascript-DSA/Heaps/.DS_Store differ diff --git a/Javascript-DSA/Heaps/AlgoExpert/kth_smallest_element.js b/Javascript-DSA/Heaps/AlgoExpert/kth_smallest_element.js new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/Heaps/AlgoExpert/laptops_used.js b/Javascript-DSA/Heaps/AlgoExpert/laptops_used.js new file mode 100644 index 00000000..f0209dd2 --- /dev/null +++ b/Javascript-DSA/Heaps/AlgoExpert/laptops_used.js @@ -0,0 +1,21 @@ +//! O(nlogn) time | O(n) space - where n is the number of times +function laptopRentals(times) { + if(times.length === 0) return 0; + + let usedLaptops = 0; + const startTimes = times.map(a => a[0]).sort((a, b) => a - b); + const endTimes = times.map(a => a[1]).sort((a, b) => a- b); + + let startIterator = 0; + let endIterator = 0; + + while(startIterator < times.length) { + if(startTimes[startIterator] >= endTimes[endIterator]) { + usedLaptops--; + endIterator++; + } + usedLaptops++; + startIterator++; + } + return usedLaptops; +} \ No newline at end of file diff --git a/Javascript-DSA/Heaps/AlgoExpert/maxHeap.js b/Javascript-DSA/Heaps/AlgoExpert/maxHeap.js new file mode 100644 index 00000000..ece88908 --- /dev/null +++ b/Javascript-DSA/Heaps/AlgoExpert/maxHeap.js @@ -0,0 +1,69 @@ +//! 02/03/2022 +class maxHeap { + constructor() { + this.heap = []; + } + upheapify(idx) { + if(idx == 0) return; + while(idx) { + let parent = Math.floor( (idx - 1) / 2); + if(this.heap[parent] > this.heap[idx]) { + break; + } else { + let temp = this.heap[idx]; + this.heap[idx] = this.heap[parent]; + this.heap[parent] = temp; + } + idx = parent; + } +} + downheapify(idx) { + let largestIdx = idx; + while(idx < this.heap.length) { + let lc = 2 * idx + 1; + let rc = 2 * idx + 2; + if(lc < this.heap.length && this.heap[lc] > this.heap[largestIdx]){ + largestIdx = lc; + } + if(rc < this.heap.length && this.heap[rc] > this.heap[largestIdx]) { + largestIdx = rc; + } + if(largestIdx == idx) break; + let temp = this.heap[idx]; + this.heap[idx] = this.heap[largestIdx]; + this.heap[largestIdx] = temp; + idx = largestIdx; + } + } + insert(element) { + this.heap.push(element); + this.upheapify(this.heap.length - 1); + } + getMax() { + return this.heap[0]; + } + pop() { + //! removes the root of heap + let temp = this.heap[0]; + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap[this.heap.length - 1] = temp; + this.heap.pop(); + this.downheapify(0); + } + display() { + console.log(this.heap); + } +} + +let heap = new maxHeap(); +heap.insert(10); +heap.insert(5); +heap.insert(9); +heap.insert(-2); +heap.insert(8); + +console.log(heap.getMax()); +heap.display(); +heap.pop(); +console.log(heap.getMax()); +heap.display(); \ No newline at end of file diff --git a/Javascript-DSA/Heaps/AlgoExpert/merge_k_sorted_sub_arrays.js b/Javascript-DSA/Heaps/AlgoExpert/merge_k_sorted_sub_arrays.js new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/Heaps/AlgoExpert/merge_sorted_arrays.js b/Javascript-DSA/Heaps/AlgoExpert/merge_sorted_arrays.js new file mode 100644 index 00000000..7904f1e2 --- /dev/null +++ b/Javascript-DSA/Heaps/AlgoExpert/merge_sorted_arrays.js @@ -0,0 +1,42 @@ +//! O(nk) time | O(n + k) space - n is the total +//! number of array elements and k is the number or arrays +function mergeSortedArrays(arrays) { + const sortedList = []; + const elementIdxs = arrays.map(() => 0); + while(true) { + const smallestItems = []; + for(let arrayIdx = 0; arrayIdx < arrays.length; arrayIdx++) { + const relevantArray = arrays[arrayIdx]; //? [1, 5, 9, 21] + const elementIdx = elementIdxs[arrayIdx]; //? 0 + if(elementIdx === relevantArray.length) continue; + smallestItems.push( { + arrayIdx, + num: relevantArray[elementIdx], + }); + } + console.log(smallestItems.length); + console.log(smallestItems); + if(smallestItems.length === 0) break; + const nextItem = getMinValue(smallestItems); + sortedList.push(nextItem.num); + elementIdxs[nextItem.arrayIdx]++; + } + return sortedList; +} + +function getMinValue(items) { + let minValueIdx = 0; + for(let i = 1; i < items.length; i++) { + if(items[i].num < items[minValueIdx].num ) minValueIdx = i; + } + return items[minValueIdx]; +} + +let arrays = [ + [1, 5, 9, 21], + [-1, 0], + [-124, 81, 121], + [3, 6, 12 ,20, 150] +]; + +console.log(mergeSortedArrays(arrays)); \ No newline at end of file diff --git a/Javascript-DSA/Heaps/buildHeap.js b/Javascript-DSA/Heaps/buildHeap.js new file mode 100644 index 00000000..ef068f73 --- /dev/null +++ b/Javascript-DSA/Heaps/buildHeap.js @@ -0,0 +1,31 @@ +//! 04/03/2022 +//! O(n) time | O(1) space + +function downheapify(arr, idx) { + let largestIdx = idx; + while(idx < arr.length) { + let lc = 2 * idx + 1; + let rc = 2 * idx + 2; + if(lc < arr.length && arr[lc] > arr[largestIdx]){ + largestIdx = lc; + } + if(rc < arr.length && arr[rc] > arr[largestIdx]) { + largestIdx = rc; + } + if(largestIdx == idx) break; + let temp = arr[idx]; + arr[idx] = arr[largestIdx]; + arr[largestIdx] = temp; + idx = largestIdx; + } +} + +function buildHeap(arr) { + for(let i = arr.length - 1; i >= 0; i--) { + downheapify(arr, i); + } + return arr; +} + +let arr = [7, 9, 1, 3, 10, -2, 6, 5]; +console.log(buildHeap(arr)); \ No newline at end of file diff --git a/Javascript-DSA/Heaps/kth_smallest_element.js b/Javascript-DSA/Heaps/kth_smallest_element.js new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/Heaps/maxHeap.js b/Javascript-DSA/Heaps/maxHeap.js new file mode 100644 index 00000000..ece88908 --- /dev/null +++ b/Javascript-DSA/Heaps/maxHeap.js @@ -0,0 +1,69 @@ +//! 02/03/2022 +class maxHeap { + constructor() { + this.heap = []; + } + upheapify(idx) { + if(idx == 0) return; + while(idx) { + let parent = Math.floor( (idx - 1) / 2); + if(this.heap[parent] > this.heap[idx]) { + break; + } else { + let temp = this.heap[idx]; + this.heap[idx] = this.heap[parent]; + this.heap[parent] = temp; + } + idx = parent; + } +} + downheapify(idx) { + let largestIdx = idx; + while(idx < this.heap.length) { + let lc = 2 * idx + 1; + let rc = 2 * idx + 2; + if(lc < this.heap.length && this.heap[lc] > this.heap[largestIdx]){ + largestIdx = lc; + } + if(rc < this.heap.length && this.heap[rc] > this.heap[largestIdx]) { + largestIdx = rc; + } + if(largestIdx == idx) break; + let temp = this.heap[idx]; + this.heap[idx] = this.heap[largestIdx]; + this.heap[largestIdx] = temp; + idx = largestIdx; + } + } + insert(element) { + this.heap.push(element); + this.upheapify(this.heap.length - 1); + } + getMax() { + return this.heap[0]; + } + pop() { + //! removes the root of heap + let temp = this.heap[0]; + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap[this.heap.length - 1] = temp; + this.heap.pop(); + this.downheapify(0); + } + display() { + console.log(this.heap); + } +} + +let heap = new maxHeap(); +heap.insert(10); +heap.insert(5); +heap.insert(9); +heap.insert(-2); +heap.insert(8); + +console.log(heap.getMax()); +heap.display(); +heap.pop(); +console.log(heap.getMax()); +heap.display(); \ No newline at end of file diff --git a/Javascript-DSA/Heaps/merge_k_sorted_sub_arrays.js b/Javascript-DSA/Heaps/merge_k_sorted_sub_arrays.js new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/Patterns/pattern1.js b/Javascript-DSA/Patterns/pattern1.js new file mode 100644 index 00000000..ea8b7365 --- /dev/null +++ b/Javascript-DSA/Patterns/pattern1.js @@ -0,0 +1,8 @@ + +for (let row = 1; row < 6; row++) { + let j = ""; + for (let col = 1; col<6; col++){ + j = j + col + " "; + } + console.log(j); +} diff --git a/Javascript-DSA/Patterns/pattern2.js b/Javascript-DSA/Patterns/pattern2.js new file mode 100644 index 00000000..8035e823 --- /dev/null +++ b/Javascript-DSA/Patterns/pattern2.js @@ -0,0 +1,7 @@ +for (let row = 1; row < 6; row++) { + let j = ""; + for (let col = 1; col <= row; col++){ + j = j + col + " "; + } + console.log(j); +} diff --git a/Javascript-DSA/Patterns/pattern3.js b/Javascript-DSA/Patterns/pattern3.js new file mode 100644 index 00000000..b31aec0d --- /dev/null +++ b/Javascript-DSA/Patterns/pattern3.js @@ -0,0 +1,7 @@ +for (let row = 1; row <= 7; row++) { + let j = ""; + for (let col = 1; col <= row; col++){ + j = j + "* "; + } + console.log(j); +} diff --git a/Javascript-DSA/Patterns/pattern4.js b/Javascript-DSA/Patterns/pattern4.js new file mode 100644 index 00000000..6e1a56f3 --- /dev/null +++ b/Javascript-DSA/Patterns/pattern4.js @@ -0,0 +1,31 @@ +let n = 11; +let row = 0; + +//? Upper Part +for (row; row <= Math.floor(n/2); row++) { + + let result = ""; + for (let spaces = 0; spaces < (n - (2*row + 1)); spaces++) { + result = result + " "; + } + + for (let stars = 0; stars < (2*row) + 1; stars++) { + result = result + "* "; + } + console.log(result); +} + +//? Lower Part + +for (row; row < n; row++) { + + let result = ""; + + for (let spaces = 0; spaces < (n - (2*(n - row) - 1)); spaces++) { + result = result + " "; + } + for (let stars = 0; stars < (2*(n - row) - 1); stars++) { + result = result + "* "; + } + console.log(result); +} \ No newline at end of file diff --git a/Javascript-DSA/Patterns/pattern5.js b/Javascript-DSA/Patterns/pattern5.js new file mode 100644 index 00000000..71298daf --- /dev/null +++ b/Javascript-DSA/Patterns/pattern5.js @@ -0,0 +1,18 @@ +let n = 4; +let row = 1; + +for (row; row <= n; row++) { + + let result = ""; + for (let spaces = 1; spaces <= 2*(n - row); spaces++) { + result = result + " "; + } +for (let i = 1; i <= row; i++ ) { + result = result + i + " "; +} +for (let j = row - 1; j >= 1; j-- ) { + result = result + j + " "; +} + console.log(result); + +} diff --git a/Javascript-DSA/Patterns/pattern6.js b/Javascript-DSA/Patterns/pattern6.js new file mode 100644 index 00000000..815b5369 --- /dev/null +++ b/Javascript-DSA/Patterns/pattern6.js @@ -0,0 +1,32 @@ +let n = 11; +let row = 0; + +for (row; row <= Math.floor(n/2); row++) { + let result = ""; + + for (let spaces = 0; spaces < (n - (2*row + 1)); spaces++) { + result = result + " "; + } + for (let i = 1; i <= row+1; i++) { + result = result + i + " "; + } + for (let j = row; j >= 1; j-- ) { + result = result + j + " "; +} + console.log(result); +} +for (row; row < n; row++) { + + let result = ""; + + for (let spaces = 0; spaces < (n - (2*(n - row) - 1)); spaces++ ) { + result = result + " "; + } + for (let i = 1; i <= (n - row ); i++) { + result = result + i + " "; + } + for (let i = ((n - row) - 1); i > 0; i--) { + result = result + i + " "; + } + console.log(result); +} \ No newline at end of file diff --git a/Javascript-DSA/Patterns/pattern7.js b/Javascript-DSA/Patterns/pattern7.js new file mode 100644 index 00000000..4b3fbe26 --- /dev/null +++ b/Javascript-DSA/Patterns/pattern7.js @@ -0,0 +1,20 @@ +let n = 4; +let row = 1; +let i = 0; + +for (row; row <= n; row++) { + + let result = ""; + for (let spaces = 1; spaces <= 2*(n - row); spaces++) { + result = result + " "; + } +for (i ; i < row; i++ ) { + result = result + (i+1) + " "; +} +// i = i-1; +// for (let j = row - 1; j >= 1; j-- ) { +// result = result + j + " "; +// } + console.log(result); + +} diff --git a/Javascript-DSA/Queues/deque.js b/Javascript-DSA/Queues/deque.js new file mode 100644 index 00000000..9d5085c2 --- /dev/null +++ b/Javascript-DSA/Queues/deque.js @@ -0,0 +1,83 @@ +//! Double ended queue +//! 10/02/2022 +class Deque { + constructor() { + this.data = []; + this.front = 0; + this.rear = 0; + + } + + isEmpty() { + return (this.rear - this.front == 0); + } + + addBack(element) { + this.data[this.rear] = element; + this.rear++; + + } + + addFront(element) { + if(this.isEmpty()) { + this.addBack(element); + } + else if(this.front == 0) { + let arr = new Array(2 * (this.rear - this.front)); + let i = arr.length - 1; + let j = this.rear - 1; + + while(j >= this.front) { + arr[i] = this.data[j]; + i--; + j--; + } + this.front = i; + this.rear = arr.length; + this.data = arr; + this.data[this.front] = element; + } + else { + this.front--; + this.data[this.front] = element; + + } + } + + + removeFront() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + return undefined; + } + + removeBack() { + if(!this.isEmpty()) { + let temp = this.data[this.rear - 1]; + this.rear--; + return temp; + } + return undefined; + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +const dequeue = new Deque(); + +dequeue.addBack(10); +dequeue.addBack(20); +dequeue.addFront(30); +console.log(dequeue.getFront()); +dequeue.removeBack(); +dequeue.removeFront(); +console.log(dequeue.getFront()); +dequeue.addFront(100); +console.log(dequeue.getFront()); \ No newline at end of file diff --git a/Javascript-DSA/Queues/largestRectangleInHistogram.js b/Javascript-DSA/Queues/largestRectangleInHistogram.js new file mode 100644 index 00000000..629d8333 --- /dev/null +++ b/Javascript-DSA/Queues/largestRectangleInHistogram.js @@ -0,0 +1,67 @@ +//! 10/02/2022 + +function nextSmaller(array) { + + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = 0; i < array.length; i++) { + + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = i; + + } + stack.push(i); + } + for(let i = 0; i < result.length; i++) { + if(result[i] == - 1) { + result[i] = result.length; + } + } + return result; +} + +function prevSmaller(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = array.length - 1; i >= 0; i--) { + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = i; + } + stack.push(i); + } + + + return result; +} + +function findArea(length, breadth) { + return length * breadth; +} +function maxArea(array) { + + let prev = prevSmaller(array); + // console.log(prev); + let next = nextSmaller(array); + // console.log(next); + let max = 0; + + for(let i = 0; i < array.length; i++) { + + let prevSmallIndex = prev[i]; + let nextSmallIndex = next[i]; + let width = nextSmallIndex - prevSmallIndex - 1; + let area = findArea(array[i], width); + max = Math.max(max, area); + + } + return max; + +} + +let array = [2, 1, 5, 6, 2, 3]; +console.log(maxArea(array)); + diff --git a/Javascript-DSA/Queues/maxForSubArray.js b/Javascript-DSA/Queues/maxForSubArray.js new file mode 100644 index 00000000..f526e0e1 --- /dev/null +++ b/Javascript-DSA/Queues/maxForSubArray.js @@ -0,0 +1,21 @@ +function a(arr, k) { + + let result = []; + for(let i = 0; i < arr.length - k + 1; i++) { + let j = i; + let p = i + k - 1; + let temp = 0; + while(j <= p) { + temp = Math.max(temp, arr[j]); + j++; + } + result.push(temp); + temp = 0; + } + return result; +} + +let arr = [1, 2, 3, 1, 0, -1, 4, 5, 2, 3, 6]; +let k = 3; + +console.log(a(arr, k)); \ No newline at end of file diff --git a/Javascript-DSA/Queues/queue.js b/Javascript-DSA/Queues/queue.js new file mode 100644 index 00000000..87569403 --- /dev/null +++ b/Javascript-DSA/Queues/queue.js @@ -0,0 +1,46 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +const queue = new Queue(); + +queue.enqueue(10); +queue.enqueue(20); +queue.enqueue(30); +queue.enqueue(40); +queue.enqueue(50); + +queue.dequeue(); +queue.dequeue(); + +console.log(queue.isEmpty()); \ No newline at end of file diff --git a/Javascript-DSA/Queues/queueUsingStack.js b/Javascript-DSA/Queues/queueUsingStack.js new file mode 100644 index 00000000..4aa7e053 --- /dev/null +++ b/Javascript-DSA/Queues/queueUsingStack.js @@ -0,0 +1,48 @@ +class Queue { + constructor() { + this.stack1 = []; + this.stack2 = []; + this.rear1 = 0; + this.front1 = 0; + this.rear2 = 0; + this.front2 = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length == 0; + } + + enqueue(element) { + this.stack1[this.rear++] = element; + } + + dequeue() { + while(this.front1 < this.rear1) { + this.stack2[this.rear2++] = this.stack1[this.front1++]; + } + let temp = this.stack1[this.front1++]; + return temp; + } + + getFront() { + if(!this.isEmpty()) { + return this.stack1[this.front]; + } + return undefined; + } +} + +const queue = new Queue(); + +queue.enqueue(10); +queue.enqueue(20); +queue.enqueue(30); +queue.enqueue(40); +queue.enqueue(50); +console.log(queue.dequeue()); + + +// console.log(queue.getFront()); \ No newline at end of file diff --git a/Javascript-DSA/Queues/reverseQueue.js b/Javascript-DSA/Queues/reverseQueue.js new file mode 100644 index 00000000..1fe4898b --- /dev/null +++ b/Javascript-DSA/Queues/reverseQueue.js @@ -0,0 +1,60 @@ + +//! 10/02/2022 +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +function reverseQueue() { + let array = []; + while(queue.length() > 0) { + array.push(queue.dequeue()); + } + + for(let i = array.length - 1; i >= 0; i--) { + queue.enqueue(array[i]); + } +} + + +const queue = new Queue(); + +queue.enqueue(10); +queue.enqueue(20); +queue.enqueue(30); +queue.enqueue(40); +queue.enqueue(50); + +reverseQueue(); + +console.log(queue.getFront()); + + diff --git a/Javascript-DSA/Queues/stackUsingQueue.js b/Javascript-DSA/Queues/stackUsingQueue.js new file mode 100644 index 00000000..e1d8dd60 --- /dev/null +++ b/Javascript-DSA/Queues/stackUsingQueue.js @@ -0,0 +1,69 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +class StackUsingQueue { + constructor() { + this.primary = new Queue(); + this.secondary = new Queue(); + + } + + push(key) { + this.primary.enqueue(key); + } + + pop() { + while(this.primary.length() > 1) { + this.secondary.enqueue(this.primary.dequeue()); + } + + let temp = this.primary.dequeue(); + + while(this.secondary.length() > 0) { + this.primary.enqueue(this.secondary.dequeue()); + } + return temp; + } + +} + + +const st = new StackUsingQueue(); + +st.push(10); +st.push(20); +st.push(30); +st.push(40); +st.push(50); + +console.log(st.pop()); \ No newline at end of file diff --git a/Javascript-DSA/Queues/tempCodeRunnerFile.js b/Javascript-DSA/Queues/tempCodeRunnerFile.js new file mode 100644 index 00000000..eb2beae1 --- /dev/null +++ b/Javascript-DSA/Queues/tempCodeRunnerFile.js @@ -0,0 +1,2 @@ + + for(let i = 0; i < result.length; i++) { \ No newline at end of file diff --git a/Javascript-DSA/Recursion/.DS_Store b/Javascript-DSA/Recursion/.DS_Store new file mode 100644 index 00000000..c3d99512 Binary files /dev/null and b/Javascript-DSA/Recursion/.DS_Store differ diff --git a/Javascript-DSA/Recursion/AlgoExpert/NthFibonacci.js b/Javascript-DSA/Recursion/AlgoExpert/NthFibonacci.js new file mode 100644 index 00000000..e1369d31 --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/NthFibonacci.js @@ -0,0 +1,33 @@ +//! https://www.algoexpert.io/questions/Nth%20Fibonacci +//! O(n) time | O(1) space + +function getNthFib(n) { + const lastTwo = [0, 1]; + let counter = 3; + while(counter <= n) { + const nextFib = lastTwo[0] + lastTwo[1]; + lastTwo[0] = lastTwo[1]; + lastTwo[1] = nextFib; + counter++; + } + return n > 1 ? lastTwo[1] : lastTwo[0]; +} + +//! O(n) time | O(n) space | DynamicProgramming + +function getNthFib(n, memoize = {1: 0, 2: 1}) { + if(n in memoize) { + return memoize[n]; + } else { + memoize[n] = getNthFib(n - 1, memoize) + getNthFib(n - 2, memoize); + return memoize[n]; + } +} + +//! O(2^n) time | O(n) space + +function getNthFib(n) { + if(n == 2) return 1; + if(n == 1) return 0; + else return getNthFib(n - 1) + getNthFib(n - 2); +} diff --git a/Javascript-DSA/Recursion/AlgoExpert/dummy.cpp b/Javascript-DSA/Recursion/AlgoExpert/dummy.cpp new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/Recursion/AlgoExpert/dummy.js b/Javascript-DSA/Recursion/AlgoExpert/dummy.js new file mode 100644 index 00000000..059f8d8c --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/dummy.js @@ -0,0 +1,101 @@ +// function fun(array) { +// let counter = Infinity; +// for(let i = 0; i < array.length; i++) { +// let sum = 0; +// if(isPowerOf2(array[i])) { +// return 1; +// }else { +// let temp = 1; +// sum = sum + array[i]; +// for(var j = 0; j < array.length; j++) { +// if(i != j) { +// sum = sum + array[j]; +// if(isPowerOf2(sum)) { +// temp++; +// counter = Math.min(counter, temp); +// break; +// } else { +// sum = sum - array[j]; +// temp--; +// } +// } +// } +// } +// } +// return counter == Infinity? -1: counter; +// } + +// function isPowerOf2(n) { +// if(n == 1) return true; +// return parseInt( (Math.ceil((Math.log(n) / Math.log(2))))) == parseInt( (Math.floor(((Math.log(n) / Math.log(2)))))); +// } + +// const array = [1, 2, 3, 1]; + +// console.log(fun(array)); +// var numJewelsInStones = function(jewels, stones) { + +// const obj = {}; +// let counter = 0; + +// for(let i = 0; i < jewels.length; i++) { +// obj[jewels[i]] = true; +// } + +// for(let i = 0; i < stones.length; i++) { +// const temp = stones[i]; +// if(obj[temp]) { +// console.log(obj); +// counter++; +// } +// } +// return counter; +// }; + +// const jewels = "aA"; +// const stones = "aAAbbbb"; + + +// console.log(numJewelsInStones(jewels, stones)) + + + +function phoneNumberMnemonics(phoneNumber) { + if(!phoneNumber) return []; + const currentMnemonic = new Array(phoneNumber.length).fill('0'); + const mnemonicsFound = []; + phoneNumberMnemonicsHelper(0, currentMnemonic, phoneNumber, mnemonicsFound); + return mnemonicsFound; +} + +function phoneNumberMnemonicsHelper(idx, currentMnemonic, phoneNumber, mnemonicsFound) { + + if(idx == phoneNumber.length) { + currentMnemonic = currentMnemonic.join(''); + mnemonicsFound.push(currentMnemonic); + return; + } else { + const digit = phoneNumber[idx]; + const letters = DIGIT_LETTERS[digit]; + for(const letter of letters) { + currentMnemonic[idx] = letter; + phoneNumberMnemonicsHelper(idx + 1, currentMnemonic, phoneNumber, mnemonicsFound); + } + } +} + +const DIGIT_LETTERS = { + 1: ['1'], + 2: ['a', 'b', 'c'], + 3: ['d', 'e', 'f'], + 4: ['g', 'h', 'i'], + 5: ['j', 'k', 'l'], + 6: ['m', 'n', 'o'], + 7: ['p', 'q', 'r', 's'], + 8: ['t', 'u', 'v'], + 9: ['w', 'x', 'y', 'z'], + 0: ['0'] +} + + +console.log(phoneNumberMnemonics('2')); \ No newline at end of file diff --git a/Javascript-DSA/Recursion/AlgoExpert/permutations.js b/Javascript-DSA/Recursion/AlgoExpert/permutations.js new file mode 100644 index 00000000..6d9325c1 --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/permutations.js @@ -0,0 +1,49 @@ +//! https://www.algoexpert.io/questions/Permutations + +//! Upper Bound: O(n^2*n!) time | O(n*n!) space +//! Roughly: O(n*n!) time | O(n*n!) space + +function getPermutations(array) { + const permutations = []; + permutationsHelper(array, [], permutations); + return permutations; +} + +function permutationsHelper(array, currentPermutation, permutations) { + if(!array.length && currentPermutation) { + permutations.push(currentPermutation); + } else { + for(let i = 0; i < array.length; i++) { + const newArray = array.slice(0, i).concat(array.slice(i + 1)); + const newPermutation = currentPermutation.concat(array[i]); + permutationsHelper(newArray, newPermutation, permutations); + } + } +} + +const array = [1, 2, 3]; + +console.log(getPermutations(array)); + +//! O(n*n!) time | O(n*n!) space +// function getPermutations(array) { +// const permutations = []; +// permutationsHelper(0, array, permutations); +// return permutations; +// } +// function permutationsHelper(i, array, permutations) { +// if(i == array.length - 1) { +// permutations.push(array.slice()); +// } else { +// for(let j = i; j < array.length; j++) { +// swap(i, j, array); +// permutationsHelper(i + 1, array, permutations); +// swap(i, j, array); +// } +// } +// } +// function swap(i, j, array) { +// const temp = array[i]; +// array[i] = array[j]; +// array[j] = temp; +// } \ No newline at end of file diff --git a/Javascript-DSA/Recursion/AlgoExpert/phoneNumberMnemonics.js b/Javascript-DSA/Recursion/AlgoExpert/phoneNumberMnemonics.js new file mode 100644 index 00000000..f4faa32f --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/phoneNumberMnemonics.js @@ -0,0 +1,38 @@ +//! https://www.algoexpert.io/questions/Phone%20Number%20Mnemonics + +function phoneNumberMnemonics(phoneNumber) { + const currentMnemonic = new Array(phoneNumber.length).fill('0'); + const mnemonicsFound = []; + + phoneNumberMnemonicsHelper(0, phoneNumber, currentMnemonic, mnemonicsFound); + return mnemonicsFound; +} +function phoneNumberMnemonicsHelper(idx, phoneNumber, currentMnemonic, mnemonicsFound) { + if(idx == phoneNumber.length) { + const mnemonic = currentMnemonic.join(''); //! O(n) time operation + mnemonicsFound.push(mnemonic); + } else { + const digit = phoneNumber[idx]; + const letters = DIGIT_LETTERS[digit]; + for(const letter of letters) { + currentMnemonic[idx] = letter; + // console.log(currentMnemonic); + phoneNumberMnemonicsHelper(idx + 1, phoneNumber, currentMnemonic, mnemonicsFound); + } + } +} + +const DIGIT_LETTERS = { + 0: ['0'], + 1: ['1'], + 2: ['a', 'b', 'c'], + 3: ['d', 'e' , 'f'], + 4: ['g', 'h', 'i'], + 5: ['j', 'k', 'l'], + 6: ['m', 'n', 'o'], + 7: ['p', 'q', 'r', 's'], + 8: ['t', 'u', 'v'], + 9: ['w', 'x', 'y', 'z'] +}; + +console.log(phoneNumberMnemonics('1905')); \ No newline at end of file diff --git a/Javascript-DSA/Recursion/AlgoExpert/powerset.js b/Javascript-DSA/Recursion/AlgoExpert/powerset.js new file mode 100644 index 00000000..c50a5412 --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/powerset.js @@ -0,0 +1,27 @@ +//! O(n*2^n) time | O(n*2^n) space +function powerset(array, idx = null) { + if(idx == null) idx = array.length - 1; + if(idx < 0) return [[]]; + const ele = array[idx]; + const subsets = powerset(array, idx - 1); + const length = subsets.length; + for(let i = 0; i < length; i++) { + const currentSubset = subsets[i]; + subsets.push(currentSubset.concat(ele)); + } + return subsets; +} +console.log(powerset([1, 2, 3])); + +//! O(n*2^n) time | O(n*2^n) space +function powerset(array) { + const subsets = [[]]; + for(const ele of array) { + const length = subsets.length; + for(let i = 0; i < length; i++) { + const currentSubset = subsets[i]; + subsets.push(currentSubset.concat(ele)); + } + } + return subsets; +} \ No newline at end of file diff --git a/Javascript-DSA/Recursion/AlgoExpert/productSum.js b/Javascript-DSA/Recursion/AlgoExpert/productSum.js new file mode 100644 index 00000000..176b0622 --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/productSum.js @@ -0,0 +1,4 @@ +function productSum(array, multipler = 1, len = array.length) { + if(len = array.length) return multipler; + +} \ No newline at end of file diff --git a/Javascript-DSA/Recursion/AlgoExpert/stairCase.js b/Javascript-DSA/Recursion/AlgoExpert/stairCase.js new file mode 100644 index 00000000..d3fa9b3f --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/stairCase.js @@ -0,0 +1,70 @@ +//! https://www.algoexpert.io/questions/Staircase%20Traversal + +//? using sliding window O(n) time | O(n) space + +function stairCaseTraversal(height, maxSteps) { + let currentNumberOfWays = 0; + const waysToTop = [1]; + + for(currentHeight = 1; currentHeight < height + 1; currentHeight++) { + const startOfWindow = currentHeight - maxSteps - 1; + const endOfWindow = currentHeight - 1; + if(startOfWindow >= 0) currentNumberOfWays -= waysToTop[startOfWindow]; + currentNumberOfWays += waysToTop[endOfWindow] + waysToTop.push(currentNumberOfWays); + } + return waysToTop[height]; +} + +//? O(n * k) time | O(n) space +function stairCaseTraversal(height, maxSteps) { + const waysToTop = new Array(height + 1).fill(0); + waysToTop[0] = 1; + waysToTop[1] = 1; + + for(let currentHeight = 2; currentHeight < height + 1; currentHeight++) { + let step = 1; + while(step <= maxSteps && step <= currentHeight) { + waysToTop[currentHeight] = waysToTop[currentHeight] + waysToTop[currentHeight - 1]; + step++; + } + } + return waysToTop[height]; +} + +//! O(n*k) time | O(n) space - where n is the height of the staircase and k is the number of allowed steps. +//todo using Dynamic Programming + +function stairCaseTraversal(height, maxSteps) { + return numberOfWaysToTop(height, maxSteps, {0: 1, 1: 1}); +} + +function numberOfWaysToTop(height, maxSteps, memoize) { + if(height in memoize) { + return memoize[height]; + } + let numberOfWays = 0; + for(let step = 1; step < Math.min(height, maxSteps) + 1; step++) { + numberOfWays += numberOfWaysToTop(height - step, maxSteps, memoize) + } + memoize[height] = numberOfWays; + + return numberOfWays; +} + +//! O(k^n) time | O(n) space - where n is the height of the staircase and k is the number of allowed steps. +function stairCaseTraversal(height, maxSteps) { + return numberOfWaysToTop(height, maxSteps); +} + +function numberOfWaysToTop(height, maxSteps) { + if(height <= 1) return 1; + + let numberOfWays = 0; + for(let step = 1; step < Math.min(height, maxSteps) + 1; step++) { + numberOfWays += numberOfWaysToTop(height - step, maxSteps); + } + return numberOfWays; +} + +console.log(stairCaseTraversal(4, 2)); \ No newline at end of file diff --git a/Javascript-DSA/Recursion/AlgoExpert/sudoku.js b/Javascript-DSA/Recursion/AlgoExpert/sudoku.js new file mode 100644 index 00000000..6c8e29bd --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/sudoku.js @@ -0,0 +1,80 @@ +function solveSudoku(board) { + solvePartialSudoku(0, 0, board); + return board; +} + +function solvePartialSudoku(row, col, board) { + let currentRow = row; + let currentCol = col; + + if(currentCol == board[currentRow].length) { + currentRow++; + currentCol = 0; + + if(currentRow == board.length) return true; + } + + if(board[currentRow][currentCol ] == 0) { + return tryDigitsAtPosition(currentRow, currentCol, board); + } + return solvePartialSudoku(currentRow, currentCol + 1, board); +} + +function tryDigitsAtPosition(row, col, board) { + for(let digit = 1; digit < 10; digit++) { + if(isValidAtPosition(digit, row, col, board)) { + board[row][col] = digit; + if(solvePartialSudoku(row, col + 1, board)) return true; + } + } + board[row][col] = 0; + return false; +} + +function isValidAtPosition(value, row, col, board) { + const rowIsValid = !board[row].includes(value); + const colIsValid = !board.map(r => r[col]).includes(value); + + if(!rowIsValid || !colIsValid) return false; + + //! check subgrid + const subgridRowStart = Math.floor(row / 3) * 3; + const subgridColStart = Math.floor(col / 3) * 3; + for(let rowIdx = 0; rowIdx < 3; rowIdx++) { + for(let colIdx = 0; colIdx < 3; colIdx++) { + const rowToCheck = subgridRowStart + rowIdx; + const colToCheck = subgridColStart + colIdx; + const existingValue = board[rowToCheck][colToCheck]; + + if(existingValue == value) return false; + } + } + return true; +} + +let board = [ + [7, 8, 0, 4, 0, 0, 1, 2, 0], + [6, 0, 0, 0, 7, 5, 0, 0, 9], + [0, 0, 0, 6, 0, 1, 0, 7, 8], + [0, 0, 7, 0, 4, 0, 2, 6, 0], + [0, 0, 1, 0, 5, 0, 9, 3, 0], + [9, 0, 4, 0, 6, 0, 0, 0, 5], + [0, 7, 0, 3, 0, 0, 0, 1, 2], + [1, 2, 0, 0, 0, 7, 4, 0, 0], + [0, 4, 9, 2, 0, 6, 0, 0, 7] +]; + +solveSudoku(board); + +display(board); + +function display(board) { + let result = "" + for(let i = 0; i < 9; i++) { + for(let j = 0; j < 9; j++) { + result += board[i][j] + " | "; + } + result += "\n"; + } + console.log(result); +} diff --git a/Javascript-DSA/Recursion/AlgoExpert/tempCodeRunnerFile.js b/Javascript-DSA/Recursion/AlgoExpert/tempCodeRunnerFile.js new file mode 100644 index 00000000..9d413293 --- /dev/null +++ b/Javascript-DSA/Recursion/AlgoExpert/tempCodeRunnerFile.js @@ -0,0 +1 @@ +counter \ No newline at end of file diff --git a/Javascript-DSA/ReddySir/.DS_Store b/Javascript-DSA/ReddySir/.DS_Store new file mode 100644 index 00000000..27028828 Binary files /dev/null and b/Javascript-DSA/ReddySir/.DS_Store differ diff --git a/Javascript-DSA/ReddySir/DAC/binarySearch.cpp b/Javascript-DSA/ReddySir/DAC/binarySearch.cpp new file mode 100644 index 00000000..65cad586 --- /dev/null +++ b/Javascript-DSA/ReddySir/DAC/binarySearch.cpp @@ -0,0 +1,70 @@ +#include + +using namespace std; + + +int binarySearch(int arr[], int i, int j, int x) { + int mid; +//! USING DAC + if (i == j) { + if (arr[i] == x) { + return i; + } + else { + return -1; + } + } + else { + mid = (i + j ) / 2; + if (x == arr[mid]) { + return mid; + } + else if (x < arr[mid]) { + binarySearch(arr, i, mid - 1, x ); + } else { + binarySearch(arr, mid + 1, j, x); + } + } + + +} +//! using loop + + +int binarySearchUsingWhileLoop (int arr[], int i, int j, int x) { + int mid; + while (i < j) { + if (i == j) { + if (arr[i] == x) { + return i; + } else { + return -1; + } + } + else { + mid = (i + j) / 2; + if (x == arr[mid]) { + return mid; + } else if (x < arr[mid]) { + j = mid - 1; + } else { + i = mid + 1; + } + + } + } +} + + +int main () { + int arr[] = {1, 2, 3, 4, 5, 6, 7, 8}; + + int i = 0; + int j = sizeof(arr) / sizeof(arr[0]); + int x = 8; + + // cout << binarySearch(arr, i, j, x) << endl; + cout << binarySearchUsingWhileLoop(arr, i, j, x) << endl; + + return 0; +} \ No newline at end of file diff --git a/Javascript-DSA/ReddySir/DAC/binarySearch.exe b/Javascript-DSA/ReddySir/DAC/binarySearch.exe new file mode 100644 index 00000000..c0709be4 Binary files /dev/null and b/Javascript-DSA/ReddySir/DAC/binarySearch.exe differ diff --git a/Javascript-DSA/ReddySir/DAC/dummy.html b/Javascript-DSA/ReddySir/DAC/dummy.html new file mode 100644 index 00000000..55a75e0c --- /dev/null +++ b/Javascript-DSA/ReddySir/DAC/dummy.html @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + Relevel + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+ + + + + diff --git a/Javascript-DSA/ReddySir/DAC/dummy.js b/Javascript-DSA/ReddySir/DAC/dummy.js new file mode 100644 index 00000000..9dff6329 --- /dev/null +++ b/Javascript-DSA/ReddySir/DAC/dummy.js @@ -0,0 +1,65 @@ +/** + * + */ + +const person = new Object(); // 1st way to create a object with + + +person.name = "A"; +person.age = 10; +person.gender = "male"; +person.dance = function() { + console.log("I am dancing"); +} +person.eat = function eat() { + console.log("I am eating"); +} + +/** + * JS object will have fields as well as functions/behaviour + * + */ + +// console.log(person.age); + +// console.log(person['age']); + +/** + * ! obj.fieldName -> access both the field and the functions + */ + +// for (k in person) { +// console.log(k); +// } + +// console.log(Object.keys(person)); + + +function makeObject(name, age, gender) { + return { + name, + age, + gender + } +} + +// console.log(makeObject(1, 2, 3)); + +/** + * ! Another way to create object + */ + +function Person(name, age, gender) { + this.name = name; + this.age = age; + this.gender = gender; +} + +const person1 = new Person(1, 2, 3); +const person2 = new Person(4, 5, 6); + +console.log(person1); + + + + diff --git a/Javascript-DSA/ReddySir/DAC/linearSearch.cpp b/Javascript-DSA/ReddySir/DAC/linearSearch.cpp new file mode 100644 index 00000000..00b73b4f --- /dev/null +++ b/Javascript-DSA/ReddySir/DAC/linearSearch.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + + +int linearSearch(int array[], int x) { + + int len = sizeof(array) / sizeof(array[0]); + int i = 0; + + while (i < len) { + if (array[i] == x) { + return i; + } i++; + } + + return 0; + +} +int main () { + + int arr[] = {1,2,3,4,5,6,7,8}; + int x = 7; + + cout << linearSearch(arr, x) << endl; + return 0; + + +} + + + diff --git a/Javascript-DSA/ReddySir/DAC/linearSearch.exe b/Javascript-DSA/ReddySir/DAC/linearSearch.exe new file mode 100644 index 00000000..034749e6 Binary files /dev/null and b/Javascript-DSA/ReddySir/DAC/linearSearch.exe differ diff --git a/Javascript-DSA/ReddySir/DAC/straightMaxMin.cpp b/Javascript-DSA/ReddySir/DAC/straightMaxMin.cpp new file mode 100644 index 00000000..7484c739 --- /dev/null +++ b/Javascript-DSA/ReddySir/DAC/straightMaxMin.cpp @@ -0,0 +1,124 @@ +// TODO WITHOUT DAC O(n) EVERY CASE | O(n) space + + +#include +using namespace std; + +// int findMaxMinWithoutDAC () { +// int array[] = {50, 70, 60, 35, 25, 75, 12}; +// int max = array[0]; +// int min = array[0]; + +// int sizeOfArray = sizeof(array) / sizeof(array[0]); + +// cout << "Array Size: " << sizeOfArray << endl; + +// for (int i = 1; i < sizeOfArray - 1; i++) +// { +// if (max < array[i]) +// { +// max = array[i]; +// } +// else if (min > array[i]) +// { +// min = array[i]; +// } +// } + +// cout << "max: " << max << " min: " << min << endl; +// return 0; +// } + +// int main() +// { +// int array[] = {50, 70, 60, 35, 25, 75, 12}; +// int firstIndex = 0; +// int lastIndex = sizeof(array) / sizeof(array[0]); + +// findMaxMinWithDAC(array, firstIndex, lastIndex); + +// return 0; +// } + +// TODO WITH DAC O(n) EVERY CASE | O(n) space + + +#include +using namespace std; + +// structure is used to return +// two values from minMax() +struct Pair +{ + int min; + int max; +}; + +struct Pair getMinMax(int arr[], int low, int high) +{ + struct Pair minmax, mml, mmr; + int mid; + + // If there is only one element + if (low == high) + { + minmax.max = arr[low]; + minmax.min = arr[low]; + return minmax; + } + + // If there are two elements + if (high == low + 1) + { + if (arr[low] > arr[high]) + { + minmax.max = arr[low]; + minmax.min = arr[high]; + } + else + { + minmax.max = arr[high]; + minmax.min = arr[low]; + } + return minmax; + } +else { + + // If there are more than 2 elements + mid = (low + high) / 2; + mml = getMinMax(arr, low, mid); + mmr = getMinMax(arr, mid + 1, high); + + // Compare minimums of two parts + if (mml.min < mmr.min) + minmax.min = mml.min; + else + minmax.min = mmr.min; + + // Compare maximums of two parts + if (mml.max > mmr.max) + minmax.max = mml.max; + else + minmax.max = mmr.max; + + return minmax; +} +} + +// Driver code +int main() +{ + int arr[] = {1000, 11, 445, + 1, 330, 3000}; + int arrSize = 6; + + struct Pair minmax = getMinMax(arr, 0, arrSize - 1); + + cout << "Minimum element is " << minmax.min << endl; + + cout << "Maximum element is " << minmax.max; + + return 0; +} + + \ No newline at end of file diff --git a/Javascript-DSA/ReddySir/DAC/straightMaxMin.exe b/Javascript-DSA/ReddySir/DAC/straightMaxMin.exe new file mode 100644 index 00000000..fa1b5e4d Binary files /dev/null and b/Javascript-DSA/ReddySir/DAC/straightMaxMin.exe differ diff --git a/Javascript-DSA/ReddySir/DAC/tempCodeRunnerFile.cpp b/Javascript-DSA/ReddySir/DAC/tempCodeRunnerFile.cpp new file mode 100644 index 00000000..112935cb --- /dev/null +++ b/Javascript-DSA/ReddySir/DAC/tempCodeRunnerFile.cpp @@ -0,0 +1,106 @@ + +// max = array[i]; +// } +// else if (min > array[i]) +// { +// min = array[i]; +// } +// } + +// cout << "max: " << max << " min: " << min << endl; +// return 0; +// } + +// int main() +// { +// int array[] = {50, 70, 60, 35, 25, 75, 12}; +// int firstIndex = 0; +// int lastIndex = sizeof(array) / sizeof(array[0]); + +// findMaxMinWithDAC(array, firstIndex, lastIndex); + +// return 0; +// } + +// TODO WITH DAC O(n) EVERY CASE | O(n) space + + +#include +using namespace std; + +// structure is used to return +// two values from minMax() +struct Pair +{ + int min; + int max; +}; + +struct Pair getMinMax(int arr[], int low, int high) +{ + struct Pair minmax, mml, mmr; + int mid; + + // If there is only one element + if (low == high) + { + minmax.max = arr[low]; + minmax.min = arr[low]; + return minmax; + } + + // If there are two elements + if (high == low + 1) + { + if (arr[low] > arr[high]) + { + minmax.max = arr[low]; + minmax.min = arr[high]; + } + else + { + minmax.max = arr[high]; + minmax.min = arr[low]; + } + return minmax; + } +else { + + // If there are more than 2 elements + mid = (low + high) / 2; + mml = getMinMax(arr, low, mid); + mmr = getMinMax(arr, mid + 1, high); + + // Compare minimums of two parts + if (mml.min < mmr.min) + minmax.min = mml.min; + else + minmax.min = mmr.min; + + // Compare maximums of two parts + if (mml.max > mmr.max) + minmax.max = mml.max; + else + minmax.max = mmr.max; + + return minmax; +} +} + +// Driver code +int main() +{ + int arr[] = {1000, 11, 445, + 1, 330, 3000}; + int arrSize = 6; + + struct Pair minmax = getMinMax(arr, 0, arrsize - 1); + + cout << "Minimum element is " << minmax.min << endl; + + cout << "Maximum element is " << minmax.max; + + return 0; +} + + \ No newline at end of file diff --git a/Javascript-DSA/Relevel/.DS_Store b/Javascript-DSA/Relevel/.DS_Store new file mode 100644 index 00000000..1fe5b912 Binary files /dev/null and b/Javascript-DSA/Relevel/.DS_Store differ diff --git a/Javascript-DSA/Relevel/Revision/.DS_Store b/Javascript-DSA/Relevel/Revision/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/Javascript-DSA/Relevel/Revision/.DS_Store differ diff --git a/Javascript-DSA/Relevel/Revision/3SumClosest.js b/Javascript-DSA/Relevel/Revision/3SumClosest.js new file mode 100644 index 00000000..262fb4d4 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/3SumClosest.js @@ -0,0 +1,32 @@ +// https://leetcode.com/problems/3sum-closest/ +function threeSumClosest(array, targetSum) { + + array.sort((a, b) => a - b); + console.log(array); + + let result = Infinity; + + for(let i = 0; i < array.length - 2; i++) { + + let left = i + 1; + let right = array.length - 1; + + while(left < right) { + const sum = array[left] + array[right] + array[i]; + + if(sum == targetSum) return sum; + else sum < targetSum ? left++ : right--; + + if(Math.abs(targetSum - sum) < Math.abs(targetSum - result)) + { + result = sum; + } + } + } + return result; +} + +const nums = [-1,2,1,-4]; +const target = 1; + +console.log(threeSumClosest(nums, target)); \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/anotherNumberSystem.js b/Javascript-DSA/Relevel/Revision/anotherNumberSystem.js new file mode 100644 index 00000000..3e43caf2 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/anotherNumberSystem.js @@ -0,0 +1,62 @@ + +function alphaSystem(str) { + let len = str.length - 1; + + let result = 0; + + for(let i = 0; i < str.length; i++) { + const char = str[i]; + const val = ALPHA[char]; + + result += val * (26 ** len--); + } + + return result; +} + +const ALPHA = { + 'A': 1, + 'B': 2, + 'C': 3, + 'D': 4, + 'E': 5, + 'F': 6, + 'G': 7, + 'H': 8, + 'I': 9, + 'J': 10, + 'K': 11, + 'L': 12, + 'M': 13, + 'N': 14, + 'O': 15, + 'P': 16, + 'Q': 17, + 'R': 18, + 'S': 19, + 'T': 20, + 'U': 21, + 'V': 22, + 'W': 23, + 'X': 24, + 'Y': 25, + 'Z': 26 +} + +const str = "AA" +console.log(alphaSystem(str)); + + + +function alphaNum(str) { + let decimalNum = 0; + for(let i = 0; i < str.length; i++) { + const unitVal = Math.pow(26, str.length - i - 1); + const currentIdxVal = str[i].charCodeAt(0) - 64; + decimalNum += unitVal * currentIdxVal; + } + return decimalNum; +} + +console.log(alphaNum('ABC')); + diff --git a/Javascript-DSA/Relevel/Revision/avgTime.js b/Javascript-DSA/Relevel/Revision/avgTime.js new file mode 100644 index 00000000..5fce233a --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/avgTime.js @@ -0,0 +1,18 @@ +function avgTime(matrix) { + + let result = 0; + + matrix.forEach(row => { + result += (row[1] - row[0]); + }); + + return Math.round(result / matrix.length); +} + +const matrix = [ + [3, 8], + [5, 9], + [1, 5] ]; + + +console.log(avgTime(matrix)); \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/eggProblem.js b/Javascript-DSA/Relevel/Revision/eggProblem.js new file mode 100644 index 00000000..c50c3b70 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/eggProblem.js @@ -0,0 +1,47 @@ +function countEmptyCells(mat) { + let count = 0; + for(let i = 0; i < mat.length; i++) { + for(let j = 0; j < mat[0].length; j++) { + if(mat[i][j] === 0) count++; + else break; + } + } + return count; +} + +let mat = []; +let line = true; +while(line) { + let inp = readline(); + if(inp) { + mat.push(inp.split(',').map(item => parseInt(item))); + } else line = false; +} +console.log(countEmptyCells(mat)); + +// const mat = [ [10, 20, 30, 40], +// [15, 25, 35, 45], +// [24, 29, 37, 48], +// [32, 33, 39, 50]]; + + +// let result = []; +// for(let row = 0; row < mat[0].length; row++) { +// let sum = 0; +// for(let col = 0; col < mat.length; col++) { +// sum += mat[col][row]; +// } +// result.push(sum); +// } + +// console.log(result); + +// let result = []; +// for(let row = 0; row < mat[0].length; row++) { +// let sum = 0; +// for(let col = 0; col < mat.length; col++) { +// sum += mat[col][row]; +// } +// result.push(sum); +// } +// console.log(result); diff --git a/Javascript-DSA/Relevel/Revision/findDifference.js b/Javascript-DSA/Relevel/Revision/findDifference.js new file mode 100644 index 00000000..d65bcc22 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/findDifference.js @@ -0,0 +1,34 @@ +// var findTheDifference = function(s, t) { + +// const obj = {}; +// for(let i = 0; i < s.length; i++) { +// if(!obj[s[i]]) obj[s[i]] = 0; +// obj[s[i]] += 1; +// } + +// let result = ""; +// for(let i = 0; i < t.length; i++) { +// if(obj[t[i]]) obj[t[i]] -= 1; +// else if(!obj[t[i]]) result += t[i] +// } +// return result; + +// let sum1 = 0; + +// for(let i = 0; i < s.length; i++) { +// sum1 += s[i].charCodeAt(); +// } +// let sum2 = 0; + +// for(let i = 0; i < t.length; i++) { +// sum2 += t[i].charCodeAt(); +// } +// return String.fromCharCode(sum2 - sum1); +// }; + +// const s = "a"; +const s = "abcde"; +// const t = "aa"; +const t = "acd"; + + diff --git a/Javascript-DSA/Relevel/Revision/luckyNumber.js b/Javascript-DSA/Relevel/Revision/luckyNumber.js new file mode 100644 index 00000000..fced01a7 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/luckyNumber.js @@ -0,0 +1,27 @@ +// https://leetcode.com/problems/lucky-numbers-in-a-matrix/ +function luckyNumber(matrix) { + + const result = []; + + for(let row = 0; row < matrix.length; row++) { + + const min = Math.min(...matrix[row]); + + const index = matrix[row].indexOf(min); + + const colValues = []; + + for(let col = 0; col < matrix[0].length; col++) { + colValues.push(matrix[col][index]) + } + + if(min == Math.max(...colValues)) result.push(min); + } + return result; +} + +// const matrix = [[3,7,8],[9,11,13],[15,16,17]]; +const matrix = [[7, 8], [1, 2]]; + + +console.log(luckyNumber(matrix)); diff --git a/Javascript-DSA/Relevel/Revision/reverseVowels.js b/Javascript-DSA/Relevel/Revision/reverseVowels.js new file mode 100644 index 00000000..1b5df93a --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/reverseVowels.js @@ -0,0 +1,34 @@ +var reverseVowels = function(s) { + + let vowelCount = []; + + for(let i = 0; i < s.length; i++) { + const letter = s[i]; + if(letter in VOWELS) vowelCount.push(letter); + } + let k = vowelCount.length - 1; + let str = s.split(''); + for(let i = 0; i < s.length; i++) { + const letter = s[i]; + if(letter in VOWELS){ + str[i] = vowelCount[k--]; + } + } + return str.join(''); +}; + +const VOWELS = { + 'a': true, + 'e': true, + 'i': true, + 'o': true, + 'u': true, + 'A': true, + 'E': true, + 'I': true, + 'O': true, + 'U': true, +} + + +console.log(reverseVowels("aA")); \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/shoePair.js b/Javascript-DSA/Relevel/Revision/shoePair.js new file mode 100644 index 00000000..a3a52058 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/shoePair.js @@ -0,0 +1,23 @@ + + +function shoePair(arr) { + + let set = new Set(); + + for(let i = 0; i < arr.length; i++) { + for(let j = 0; j < arr[i].length; j++) { + set.add(arr[i][j]); + } + } + + let result = []; + + for (const item of set.values()) { + let temp = [item, item]; + result.push(temp); + } + return result; +} +const matrix = [[3,3,8],[9,8,9],[15,15]]; + +console.log(shoePair(matrix)); \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/simplifyPath.js b/Javascript-DSA/Relevel/Revision/simplifyPath.js new file mode 100644 index 00000000..6b64afa1 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/simplifyPath.js @@ -0,0 +1,27 @@ + +// https://leetcode.com/problems/simplify-path/ +var simplifyPath = function(path) { + + let startingWithSlash = path[0] === '/'; + let tokens = path.split('/').filter(isImportantToken); + let stack = []; + + if(startingWithSlash) stack.push(''); + + for(const token of tokens) { + if(token === '..') { + if(stack.length == 0 || stack[stack.length - 1] === '..') + stack.push(token); + else if(stack[stack.length - 1] !== '') + stack.pop(); + } else { + stack.push(token); + } + } + if(stack.length === 1 && stack[stack.length - 1] === '') return '/'; + return stack.join('/'); +}; + +function isImportantToken(token) { + return token.length > 0 && token !== '.'; +} \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/sortStudents.js b/Javascript-DSA/Relevel/Revision/sortStudents.js new file mode 100644 index 00000000..9ce32e42 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/sortStudents.js @@ -0,0 +1,26 @@ +function ordering(arr, m, n) { + + let result = [...Array(m)].map(e => Array(n)); + + let newArr = []; + + for(let i = 0; i < m; i++) { + for(let j = 0; j < n; j++) { + newArr.push(arr[i][j]); + } + } + newArr.sort((a, b) => a - b); + + let k = 0; + for(let i = 0; i < m; i++) { + for(let j = 0; j < n; j++) { + result[i][j] = newArr[k]; + k++; + } + } + return result; + +} + +const arr = [[3, 8, 7], [16, 15, 7], [11, 9, 6]]; +console.log(ordering(arr, 3, 3)); \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/specialPositions.js b/Javascript-DSA/Relevel/Revision/specialPositions.js new file mode 100644 index 00000000..0749f91f --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/specialPositions.js @@ -0,0 +1,45 @@ +// https://leetcode.com/problems/special-positions-in-a-binary-matrix/ + +var numSpecial = function(mat) { + + const rowSum = []; + const colSum = []; + + // sum of all rows + for(let i = 0; i < mat.length; i++) { + rowSum[i] = 0; + for(j = 0; j < mat[0].length; j++) { + rowSum[i] += mat[i][j]; + } + } + // Sum of all cols + for(let i = 0; i < mat[0].length; i++) { + + colSum[i] = 0; + for(let j = 0; j < mat.length; j++) { + colSum[i] += mat[j][i]; + } + } + let count = 0; + for(let i = 0; i < mat.length; i++) { + for(let j = 0; j < mat[0].length; j++) { + if(mat[i][j] == 1 && rowSum[i] == 1 && colSum[j] == 1) { + count += 1; + + } + } + } +return count; +}; + +// const matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1] ]; +// const matrix = [[0,0,0,0,0,1,0,0], +// [0,0,0,0,1,0,0,1], +// [0,0,0,0,1,0,0,0], +// [1,0,0,0,1,0,0,0], +// [0,0,1,1,0,0,0,0]]; +// const matrix = [[0,0,1,0],[0,0,0,0],[0,0,0,0],[0,1,0,0]]; +const matrix = [[1,0,0],[0,0,1],[1,0,0]]; + + +console.log(numSpecial(matrix)); \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/stringStrength.js b/Javascript-DSA/Relevel/Revision/stringStrength.js new file mode 100644 index 00000000..fd703c2a --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/stringStrength.js @@ -0,0 +1,22 @@ +function stringStrength(str) { + let longest = [0, 1]; + let startIdx = 0; + let lastSeen = {}; + + for(let i = 0; i < str.length; i++) { + const char = str.charAt(i); + if(char in lastSeen) { + startIdx = Math.max(startIdx, lastSeen[char] + 1); + } + if(longest[1] - longest[0] < i + 1 - startIdx) { + longest = [startIdx, i + 1]; + } + lastSeen[char] = i; + } + + const longestStringLength = str.slice(longest[0], longest[1]).length; + + return ((longestStringLength / str.length) * 100).toFixed(2); +} + +console.log(stringStrength("cccc")); \ No newline at end of file diff --git a/Javascript-DSA/Relevel/Revision/transposeMatrix.js b/Javascript-DSA/Relevel/Revision/transposeMatrix.js new file mode 100644 index 00000000..7f8508e9 --- /dev/null +++ b/Javascript-DSA/Relevel/Revision/transposeMatrix.js @@ -0,0 +1,39 @@ +function transposeMatrix(matrix) { + + let result = [...Array(matrix[0].length)].map(e => Array(matrix.length)); + + console.log(result); + + for(let i = 0; i < result.length; i++) { + for(let j = 0; j < result[0].length; j++) { + result[i][j] = matrix[j][i]; + } + } + return result; +} + +const matrix = [[1,4],[2,5],[3,6]]; + + + +console.log(transposeMatrix(matrix)); + + +function addMatrices(matrix1, matrix2) { + + const result = [...Array(matrix1.length)].map(e => Array(matrix1[0].length)); + + for(let i = 0; i < matrix1.length; i++) { + for(let j = 0; j < matrix1[0].length; j++) { + result[i][j] = matrix1[i][j] + matrix2[i][j]; + } + } + return result; +} + +const matrix1 = [[4, 5], + [6, 7]]; +const matrix2 = [[1, 2], + [3, 8]]; + +console.log(addMatrices(matrix1, matrix2)); \ No newline at end of file diff --git a/Javascript-DSA/Searching/AlgoExpert/binarySearch.js b/Javascript-DSA/Searching/AlgoExpert/binarySearch.js new file mode 100644 index 00000000..9c54e4d2 --- /dev/null +++ b/Javascript-DSA/Searching/AlgoExpert/binarySearch.js @@ -0,0 +1,37 @@ + +function binarySearch(array, target) { + return binarySearchHelper(array, target, 0, array.length - 1); +} + +//! O(nlogn) time | O(1) space +function binarySearchHelper(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + if(target == potentialMatch) { + return middle; + } else if(target < potentialMatch) { + right = middle - 1; + } else { + left = middle + 1; + } + } + return -1; +} + +//! O(nlogn) time | O(logn) space +function binarySearchHelper(array, target, left, right) { + + if(left > right) return -1; + + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + if(target == potentialMatch) { + return middle; + } else if(target < potentialMatch) { + return binarySearchHelper(array, target, left, middle - 1); + } else { + return binarySearchHelper(array, target, middle + 1, right); + } +} \ No newline at end of file diff --git a/Javascript-DSA/Searching/AlgoExpert/findThreeLargestNumbers.js b/Javascript-DSA/Searching/AlgoExpert/findThreeLargestNumbers.js new file mode 100644 index 00000000..1ad7b7c5 --- /dev/null +++ b/Javascript-DSA/Searching/AlgoExpert/findThreeLargestNumbers.js @@ -0,0 +1,70 @@ +//! O(n) time | O(1) space +function findThreeLargestNumbers(array) { + const threeLargest = [null, null, null]; + for(const num of array) { + updateLargest(threeLargest, num); + } + return threeLargest; +} + +function updateLargest(threeLargest, num) { + if (threeLargest[2] == null | num > threeLargest[2]) { + shiftAndUpdate(threeLargest, num, 2); + } else if(threeLargest[1] == null || num > threeLargest[1]) { + shiftAndUpdate(threeLargest, num, 1); + } else if(threeLargest[0] == null || num > threeLargest[0]) { + shiftAndUpdate(threeLargest, num, 0); + } +} + +function shiftAndUpdate(array, num, idx) { + for(let i = 0; i <= idx; i++) { + if(i == idx) { + array[idx] = num; + } else { + array[i] = array[i + 1]; + } + } +} + + +//! O(n) time | O(1) space +function findThreeLargestNumbers(array) { + let firstLargest = -Infinity; + let firstLargestIdx; + let secondLargest = -Infinity; + let secondLargestIdx; + let thirdLargest = -Infinity; + let thirdLargestIdx; + for (let i = 0; i < array.length; i++) { + if (array[i] > firstLargest) { + firstLargestIdx = i; + firstLargest = array[i]; + } + } + swap(firstLargestIdx, 0, array); + for (let i = 1; i < array.length; i++) { + if (array[i] > secondLargest) { + secondLargestIdx = i; + secondLargest = array[i]; + } + } + swap(secondLargestIdx, 1, array); + for (let i = 2; i < array.length; i++) { + if (array[i] > thirdLargest) { + thirdLargestIdx = i; + thirdLargest = array[i]; + } + } + swap(thirdLargestIdx, 2, array); + + swap(0, 2, array); + return [array[0], array[1], array[2]] + +} + +function swap(a, b, array) { + let temp = array[a]; + array[a] = array[b]; + array[b] = temp; +} diff --git a/Javascript-DSA/Searching/AlgoExpert/indexEqualsValue.js b/Javascript-DSA/Searching/AlgoExpert/indexEqualsValue.js new file mode 100644 index 00000000..e273fe7e --- /dev/null +++ b/Javascript-DSA/Searching/AlgoExpert/indexEqualsValue.js @@ -0,0 +1,48 @@ +function indexEqualsValue(array) { + return indexEqualsValueHelper(array, 0, array.length - 1); +} + +//! O(n) time | O(1) space +function indexEqualsValueHelper(array, leftIndex, rightIndex) { + while(leftIndex <= rightIndex) { + const middleIndex = rightIndex + Math.floor( (rightIndex - leftIndex) / 2 ); + const middleValue = array[middleIndex]; + if(middleValue < middleIndex) { + leftIndex = middleIndex + 1; + } else if(middleValue == middleIndex && middleIndex == 0) { + return middleIndex; + } else if(middleValue == middleIndex && array[middleIndex - 1] < middleValue - 1) { + return middleIndex; + } else { + rightIndex = middleIndex - 1; + } + } + return -1; +} +//! O(logn) time | O(logn) space +function indexEqualsValueHelper(array, leftIndex, rightIndex) { + if(leftIndex > rightIndex) return -1; + + const middleIndex = rightIndex + Math.floor( (rightIndex - leftIndex) / 2 ); + const middleValue = array[middleIndex]; + + if(middleValue < middleIndex) { + return indexEqualsValueHelper(array, middleIndex + 1, rightIndex); + } else if(middleValue == middleIndex && middleIndex == 0) { + return middleIndex; + } else if(middleValue == middleIndex && array[middleIndex - 1] < middleValue - 1) { + return middleIndex; + } else { + return indexEqualsValueHelper(array, leftIndex, middleIndex - 1); + } +} + +//! O(n) time | O(1) space +function indexEqualsValue(array) { + + for(let i = 0; i < array.length; i++) { + const value = array[i]; + if(i == value) return i; + } + return -1; +} \ No newline at end of file diff --git a/Javascript-DSA/Searching/AlgoExpert/quickSelect.js b/Javascript-DSA/Searching/AlgoExpert/quickSelect.js new file mode 100644 index 00000000..9d5d1e3b --- /dev/null +++ b/Javascript-DSA/Searching/AlgoExpert/quickSelect.js @@ -0,0 +1,45 @@ +//! https://leetcode.com/problems/kth-largest-element-in-an-array/ + +//! aka kth-largest-element-in-an-array + +//! Best: O(n) time | O(1) space +//! Average: O(n) time | O(1) space +//! Worst: O(n^2) time | O(1) space + +function quickSelect(array, k) { + const position = k - 1; + return quickSelectHelper(array, 0, array.length - 1, position); +} + +function quickSelectHelper(array, startIdx, endIdx, position) { + + while (true) { + if (startIdx > endIdx) { + throw new Error('Algorithm should never arrive here!'); + } + let i = startIdx; + let pivot = array[i]; + for (let j = i + 1; j <= endIdx; j++) { + if (array[j] < pivot) { + i++; + swap(i, j, array); + } + } + swap(startIdx, i, array); + if (i == position) { + return array[position]; + } else if (i < position) { + startIdx = i + 1; + } else { + endIdx = i - 1; + } + } +} +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +const array = [8, 5, 2, 9, 7, 6, 3]; +const k = 3 + +console.log(quickSelect(array, k)); \ No newline at end of file diff --git a/Javascript-DSA/Searching/AlgoExpert/searchForRange.js b/Javascript-DSA/Searching/AlgoExpert/searchForRange.js new file mode 100644 index 00000000..4567670e --- /dev/null +++ b/Javascript-DSA/Searching/AlgoExpert/searchForRange.js @@ -0,0 +1,115 @@ +//! https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ +//! FAANG + +function searchForRange(array, target) { + const finalRange = [-1, -1]; + alteredBinarySearch(array, target, 0, array.length - 1, finalRange, true); + alteredBinarySearch(array, target, 0, array.length - 1, finalRange, false); + return finalRange; +} + +//! O(logn) time | O(1) space +function alteredBinarySearch(array, target, left, right, finalRange, goLeft) { + + while(left <= right) { + + const mid = Math.floor( (left + right) / 2); + + if(target < array[mid]) { + right = mid - 1; + } else if(target > array[mid]) { + left = mid + 1; + } else { + if(goLeft) { + if(mid == 0 || array[mid - 1] != target) { + finalRange[0] = mid; + return; + } else { + right = mid -1; + } + } else { + if(mid == array.length - 1 || array[mid + 1] != target) { + finalRange[1] = mid; + return; + } else { + left = mid + 1; + } + } + } + } +} + +//! O(logn) time | O(logn) space +function alteredBinarySearch(array, target, left, right, finalRange, goLeft) { + if(left > right) return; + + const mid = Math.floor( (left + right) / 2); + + if(target < array[mid]) { + alteredBinarySearch(array, target, left, mid - 1, finalRange, goLeft); + } else if(target > array[mid]) { + alteredBinarySearch(array, target, mid + 1, right, finalRange, goLeft); + } else { + if(goLeft) { + if(mid == 0 || array[mid - 1] != target) { + finalRange[0] = mid; + return; + } else { + alteredBinarySearch(array, target, left, mid - 1, finalRange, goLeft); + } + } else { + if(mid == array.length - 1 || array[mid + 1] != target) { + finalRange[1] = mid; + return; + } else { + alteredBinarySearch(array, target, mid + 1, right, finalRange, goLeft); + } + } + } +} + + +function searchForRange(array, target) { + return searchForRangeHelper(array, target, 0, array.length - 1); +} + +function searchForRangeHelper(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor( (left + right) / 2); + const potentialMatch = array[middle]; + + if(target == potentialMatch) { + const startIdx = linearSearch(array, target, 0, middle); + const endIdx = findLastIdx(array, target, middle + 1, right); + return [startIdx, endIdx]; + } else if(target < potentialMatch) { + right = middle - 1; + } else if(target > potentialMatch) { + left = middle + 1; + } + } return [-1, -1]; +} + +function linearSearch(array, target, left, right) { + for(let i = 0; i <= right; i++) { + if(array[i] == target) { + return i; + } + } +} + +function findLastIdx(array, target, left, right) { + let idx; + for(let i = left; i <= right; i++) { + if(array[i] == target) { + idx = i; + } + } + return idx; +} + +let array = [0, 1, 21, 33, 45, 45, 45, 45, 45, 45, 61, 71, 73]; +const target = 45; + +console.log(searchForRange(array, target)); \ No newline at end of file diff --git a/Javascript-DSA/Searching/AlgoExpert/searchInSortedMatrix.js b/Javascript-DSA/Searching/AlgoExpert/searchInSortedMatrix.js new file mode 100644 index 00000000..35af94d7 --- /dev/null +++ b/Javascript-DSA/Searching/AlgoExpert/searchInSortedMatrix.js @@ -0,0 +1,16 @@ +//! O(n + m) time | O(1) space + +function searchInSortedMatrix(matrix, target) { + let row = 0; + let col = matrix[0].length - 1; + + while(row < matrix.length && col >= 0) { + if(matrix[row][col] > target) { + col--; + } else if(matrix[row][col] < target) { + row++; + } else { + return [row, col]; + } + } return [-1, -1]; +} \ No newline at end of file diff --git a/Javascript-DSA/Searching/AlgoExpert/shiftedBinarySearch.js b/Javascript-DSA/Searching/AlgoExpert/shiftedBinarySearch.js new file mode 100644 index 00000000..e231419f --- /dev/null +++ b/Javascript-DSA/Searching/AlgoExpert/shiftedBinarySearch.js @@ -0,0 +1,93 @@ +function shiftedBinarySearch(array, target) { + return shiftedBinarySearchHelper(array, target, 0, array.length - 1); +} + +//! O(logn) time | O(1) space +function shiftedBinarySearchHelper(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + const leftNum = array[left]; + const rightNum = array[right]; + + if(target == potentialMatch) return middle; + else if(leftNum <= potentialMatch) { + if(target < potentialMatch && target >= leftNum) { + right = middle - 1; + } else { + left = middle + 1; + } + } else { + if(target > potentialMatch && target <= rightNum) { + left = middle + 1; + } else { + right = middle - 1; + } + } + } return -1; +} + +//! O(logn) time | O(logn) space +function shiftedBinarySearchHelper(array, target, left, right) { + if(left > right) return -1; + + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + const leftNum = array[left]; + const rightNum = array[right]; + + if(target == potentialMatch) return middle; + else if(leftNum <= potentialMatch) { + if(target < potentialMatch && target >= leftNum) { + return shiftedBinarySearchHelper(array, target, left, middle - 1); + } return shiftedBinarySearchHelper(array, target, middle + 1, right); + } else { + if(target > potentialMatch && target <= rightNum) { + return shiftedBinarySearchHelper(array, target, middle + 1, right); + } + return shiftedBinarySearchHelper(array, target, left, middle - 1); + } +} + +//! O(n) time | O(1) space + +function shiftedBinarySearch(array, target) { + + let idx; + for(let i = 0; i < array.length - 1; i++) { + if(array[i] > array[i + 1]) { + idx = i; + break; + } + } + let isFound = binarySearch(array, target, 0, idx); + + if(isFound != -1) { + return isFound; + } + return binarySearch(array, target, idx + 1, array.length - 1); + +} + +function binarySearch(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + console.log(potentialMatch); + if(target == potentialMatch) { + return middle; + } else if(target < potentialMatch) { + right = middle - 1; + } else if (target > potentialMatch) { + left = middle + 1; + } + } + return -1; +} + +let array = [45, 61, 72, 72, 73, 0, 1, 21, 33, 37]; +const target = 33; + +console.log(shiftedBinarySearch(array, target)); \ No newline at end of file diff --git a/Javascript-DSA/Searching/aggresive_cows.js b/Javascript-DSA/Searching/aggresive_cows.js new file mode 100644 index 00000000..afede737 --- /dev/null +++ b/Javascript-DSA/Searching/aggresive_cows.js @@ -0,0 +1,30 @@ +function can_we_put_c_cows_with_min_dist_d(d, cows, stalls) { + let last_placed_cow_pos = stalls[0]; + let no_of_cows_placed = 1; + for(let i = 1; i < stalls.length; i++) { + let dist = stalls[i] - last_placed_cow_pos; + if(dist >= d) { + no_of_cows_placed++; + last_placed_cow_pos = stalls[i]; + } + if(no_of_cows_placed == cows) { + return true; + } + } + return false; +} +function place_cows(cows, stalls) { + stalls.sort( (a, b) => a - b ); + let l = 1, r = stalls[stalls.length - 1] - stalls[0]; + let ans = 1; + while(l <= r) { + let mid = l + Math.floor( (r - l) / 2); + if(can_we_put_c_cows_with_min_dist_d(mid, cows, stalls)) { + ans = mid; + l = mid + 1; + } else r = mid - 1; + } + return ans; +} + +console.log(place_cows(3, [1, 2, 8, 4, 9])); \ No newline at end of file diff --git a/Javascript-DSA/Searching/allocate_min_no_of_pages.js b/Javascript-DSA/Searching/allocate_min_no_of_pages.js new file mode 100644 index 00000000..db514597 --- /dev/null +++ b/Javascript-DSA/Searching/allocate_min_no_of_pages.js @@ -0,0 +1,34 @@ +//! Time O(logn * n) | space O(1) +function isAllocationPossible(array, students, m) { + let allocated_students = 1; + let pages = 0; + for(let i = 0; i < array.length; i++) { + if(array[i] > m) return false; + if(pages + array[i] > m) { + allocated_students++; + pages += array[i]; + } else { + pages += array[i]; + } + } + if(allocated_students > students) { + return false; + } return true; +} +function allocate_min_no_of_pages(books, students) { + if(books < students) return -1; + let ans = 0; + let low = Math.min(...books); //! min in array + let high = books.reduce( (a, b) => a + b); // ! sum of array elements + while(low <= high) { + let mid = Math.floor((low + high) / 2); + if(isAllocationPossible(books, students, mid)) { + ans = mid; + high = mid - 1; + } else low = mid + 1; + } + return ans; +} +let array = [12, 34, 67, 90]; +let students = 2; +console.log(allocate_min_no_of_pages(array, students)); diff --git a/Javascript-DSA/Searching/binarySearch.js b/Javascript-DSA/Searching/binarySearch.js new file mode 100644 index 00000000..d460d5d0 --- /dev/null +++ b/Javascript-DSA/Searching/binarySearch.js @@ -0,0 +1,44 @@ +//! Reddy sir approach + +// function binarySearch(array, i, j, x) { +// if(i == j) { +// if(array[i] == x) return i; +// else return -1; +// } +// else { +// let mid = Math.floor((i + j) / 2); +// if(x == array[mid]) return mid; +// else if(x < array[mid]) +// return binarySearch(array, i, mid - 1, x); +// else return binarySearch(array, mid + 1, j, x); +// } +// } + +function binarySearch(array, i, j, x) { + while(i <= j) { + if(i == j) { + if(x == array[i]) return i; + else return -1; + } + else { + let mid = Math.floor((i + j) / 2); + if(x == array[mid]) return mid; + else if(x < array[mid]) j = mid - 1; + else i = mid + 1; + } + } +} + +// let array = [1, 2, 5, 7, 13, 15, 16, 18, 24, 28, 29]; +let array = [2, 3, 3, 4, 4, 4, 5, 6, 8]; +let target = 8; + +console.log(binarySearch(array, 0, array.length - 1, target)); + + +/** + * ! modified mid formula + *! (low + high + low - low) / 2 + *? (2low + high - low) / 2 + *? (low + ((high - low) / 2)) + */ \ No newline at end of file diff --git a/Javascript-DSA/Searching/dummy.html b/Javascript-DSA/Searching/dummy.html new file mode 100644 index 00000000..392727e9 --- /dev/null +++ b/Javascript-DSA/Searching/dummy.html @@ -0,0 +1,16 @@ +#!/bin/bash + +yum update -y +yum install httpd -y +systemctl start httpd +systemctl enable httpd +cd /var/www/html + +echo "

Hi From Amazon web services Mumbai cloud server , once upon a time
I'm your friend in GURU NANAK INSTITUTIONS||
+ NARAYANA JR COLLEGE ||
+ KESHAVAREDDY SCHOOL

" > index.html + + + + + diff --git a/Javascript-DSA/Searching/knuth_morris_pratt.js b/Javascript-DSA/Searching/knuth_morris_pratt.js new file mode 100644 index 00000000..51518b8b --- /dev/null +++ b/Javascript-DSA/Searching/knuth_morris_pratt.js @@ -0,0 +1,40 @@ +//! O(m + n) + +function longest_prefix_suffix(str) { + let lps = []; + lps[0] = 0; + let len = 0; + for(let i = 1; i < str.length;) { + if(str[len] === str[i]) { + len += 1; + lps[i] = len; + i+=1; + } else { + if(len == 0) { + lps[i] = 0; + i += 1; + } else { + len = lps[len-1]; + } + } + } + return lps; +} +function knuth_morris_pratt(str, pattern) { + let n = str.length; + let m = pattern.length; + let i = 0, j = 0; + let lps = longest_prefix_suffix(pattern); + while(i < n && j < m) { + if(str[i] == pattern[j]) { + i++; + j++; + } else { + if(j == 0) i++; + else j = lps[j - 1]; + } + } + if(j == m) return true; + return false; +} +console.log(knuth_morris_pratt("aefoaefcdaefcdaed", "aefcdaed")); \ No newline at end of file diff --git a/Javascript-DSA/Searching/linearSearch.js b/Javascript-DSA/Searching/linearSearch.js new file mode 100644 index 00000000..30c2ed87 --- /dev/null +++ b/Javascript-DSA/Searching/linearSearch.js @@ -0,0 +1,8 @@ +function linearSearch(array, target) { + for(let i = 0; i < array.length; i++) { + if(arr[i] === target) return i; + } + return NaN; +} + + diff --git a/Javascript-DSA/Searching/longest_palindrome_prefix.js b/Javascript-DSA/Searching/longest_palindrome_prefix.js new file mode 100644 index 00000000..69346e61 --- /dev/null +++ b/Javascript-DSA/Searching/longest_palindrome_prefix.js @@ -0,0 +1,23 @@ +function longest_palindrome_prefix(str) { + str = str + "$" + str.split("").reverse().join(""); + console.log(str); + let lps = []; + lps[0] = 0; + let len = 0; + for(let i = 1; i < str.length;) { + if(str[len] === str[i]) { + len += 1; + lps[i] = len; + i+=1; + } else { + if(len == 0) { + lps[i] = 0; + i += 1; + } else { + len = lps[len-1]; + } + } + } + return Math.max(...lps); +} +console.log(longest_palindrome_prefix("aabbc")); \ No newline at end of file diff --git a/Javascript-DSA/Searching/longest_proper_prefix.js b/Javascript-DSA/Searching/longest_proper_prefix.js new file mode 100644 index 00000000..9f89dff7 --- /dev/null +++ b/Javascript-DSA/Searching/longest_proper_prefix.js @@ -0,0 +1,21 @@ +function longest_prefix_suffix(str) { + let lps = []; + lps[0] = 0; + let len = 0; + for(let i = 1; i < str.length;) { + if(str[len] === str[i]) { + len += 1; + lps[i] = len; + i+=1; + } else { + if(len == 0) { + lps[i] = 0; + i += 1; + } else { + len = lps[len-1]; + } + } + } + return lps; +} +console.log(longest_prefix_suffix("abcabcabc")); \ No newline at end of file diff --git a/Javascript-DSA/Searching/lowerBound.js b/Javascript-DSA/Searching/lowerBound.js new file mode 100644 index 00000000..9537f3b6 --- /dev/null +++ b/Javascript-DSA/Searching/lowerBound.js @@ -0,0 +1,22 @@ +//! Given a sorted Array and a element x, find the first element +//! element in the array that less than x. + +function lowerBound(array, target) { + let l = 0; + let r = array.length - 1; + let ans = -1; + while(l <= r) { + let mid = Math.floor( (l + r) / 2); + if(array[mid] >= target) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + if(ans == -1) return NaN; //! if every element < target + return ans; +} + +let array = [1, 2, 2, 3, 3, 4, 6, 7]; +let target = 6; + + diff --git a/Javascript-DSA/Searching/minCharForPalindrome.js b/Javascript-DSA/Searching/minCharForPalindrome.js new file mode 100644 index 00000000..feb8be3b --- /dev/null +++ b/Javascript-DSA/Searching/minCharForPalindrome.js @@ -0,0 +1,22 @@ +//!25/02/2022 + +function minChForPalindrome(s) { + let n = s.length; + let p = 31; + let m = 1000000007; + let h1 = 0; + let h2 = 0; + let pow = 1; + let ans = -1; + for(let i = 0; i < n; i++, pow = pow*p%m) { + h1 = (h1*p + s.charCodeAt(i))%m; + // console.log(h1); + h2 = (h2 + (s.charCodeAt(i))*pow)%m; + // console.log(h2); + if(h1 == h2) ans = i; + } + return n - ans - 1; +} + +console.log(minChForPalindrome("abac")); + diff --git a/Javascript-DSA/Searching/no_of_rectangles.js b/Javascript-DSA/Searching/no_of_rectangles.js new file mode 100644 index 00000000..cbe49a92 --- /dev/null +++ b/Javascript-DSA/Searching/no_of_rectangles.js @@ -0,0 +1,18 @@ +function can_we_fit_n_rect_in_sq_of_m(n, w, h, m) { + return (Math.floor(m / w) * Math.floor(m / h)) >= n; +} + +function min_rect(n, w, h) { + let l = 1, r = Math.max(w, h)*n; + let ans = 0; + while(l <= r) { + let mid = l + Math.floor( (r - l) / 2); + if(can_we_fit_n_rect_in_sq_of_m(n, w, h, mid)) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + return ans; +} + +console.log(min_rect(10, 2, 3)); \ No newline at end of file diff --git a/Javascript-DSA/Searching/notATriangle.js b/Javascript-DSA/Searching/notATriangle.js new file mode 100644 index 00000000..d4e41450 --- /dev/null +++ b/Javascript-DSA/Searching/notATriangle.js @@ -0,0 +1,27 @@ + function upper_bound(array, target) { + let left = 0; + let right = array.length - 1; + let ans = -1; + while(left <= right) { + let mid = Math.floor( (left + right) / 2); + if(array[mid] > target) { + ans = mid; + right = mid - 1; + } else left = mid + 1; + } + if (ans == -1) return array.length; + return ans; +} +function triangle(array) { + array.sort( (a, b) => a - b); + let len = array.length; + let ans = 0; + for(let i = 0; i < len; i++) { + for(let j = i + 1; j < len - 1; j++) { + const sum = array[i] + array[j]; + ans += len - upper_bound(array, sum); + } + } + return ans; +} +console.log(triangle([4, 2, 10])); \ No newline at end of file diff --git a/Javascript-DSA/Searching/printing_copies.js b/Javascript-DSA/Searching/printing_copies.js new file mode 100644 index 00000000..a64dd73e --- /dev/null +++ b/Javascript-DSA/Searching/printing_copies.js @@ -0,0 +1,20 @@ +function can_i_make_copies_in_m_seconds(m, x, y, d) { +// m --> is the time, d --> requires number of copies, x & y are the speed of machines +return (Math.floor(m / x) + Math.floor(m / y) >= d); +} + +function min_time_for_n_copies(x, y, n) { + if(n == 1) return Math.min(x, y, n); + let l = 0, r = Math.max(x, y) * n; + let ans = 0; + while(l <= r) { + let mid = l + Math.floor( (r - l) / 2); + if(can_i_make_copies_in_m_seconds(mid, x, y, n - 1)) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + return ans + Math.min(x, y); +} + +console.log(min_time_for_n_copies(1, 2, 5)); \ No newline at end of file diff --git a/Javascript-DSA/Searching/rabin_karp.js b/Javascript-DSA/Searching/rabin_karp.js new file mode 100644 index 00000000..f6e37e1e --- /dev/null +++ b/Javascript-DSA/Searching/rabin_karp.js @@ -0,0 +1,36 @@ +//!25/02/2022 +function rabin_karp(s, p) { + let prime = 31; + let m = 1000000007; //! 10^9 + 70 + let p_pow = [1]; + for(let i = 1; i < s.length; i++) { + p_pow[i] = (p_pow[i-1]*prime)%m; + } + // console.log(p_pow); + let p_h = [0]; + for(let i = 0; i < s.length; i++) { + p_h[i + 1] = (p_h[i] + (s.charCodeAt(i)*p_pow[i])%m) %m; + } + // console.log(p_h); + let hash_pat = 0; + for(let i = 0; i < p.length; i++) { + hash_pat = (hash_pat + (p.charCodeAt(i)*p_pow[i])%m)%m; + } + // console.log(hash_pat); + for(let i = 0; i <= s.length - p.length; i++) { + let curr_substring_hash = (p_h[i+p.length] - p_h[i] + m)%m; + if(curr_substring_hash == (hash_pat*p_pow[i])%m) { + //! manual match + console.log(curr_substring_hash); + let flag = true; + for(let j = 0; j < p.length; j++) { + if(s[i + j] != p[j]) { + flag = false; + break; + } + } + if(flag) console.log(i); + } + } +} +rabin_karp("aabbabcbbaabcab", "abc"); \ No newline at end of file diff --git a/Javascript-DSA/Searching/sexTuples.js b/Javascript-DSA/Searching/sexTuples.js new file mode 100644 index 00000000..5dbf7b1b --- /dev/null +++ b/Javascript-DSA/Searching/sexTuples.js @@ -0,0 +1,60 @@ +function lower_bound(array, target) { + let left = 0; + let right = array.length - 1; + let ans = -1; + while(left <= right) { + let mid = Math.floor((left + right) / 2); + if(array[mid] >= target) { + ans = mid; + right = mid - 1; + } else left = mid + 1; + } + if(ans == -1) return NaN; + return ans; +} + function upper_bound(array, target) { + let left = 0; + let right = array.length - 1; + let ans = -1; + while(left <= right) { + let mid = Math.floor( (left + right) / 2); + if(array[mid] > target) { + ans = mid; + right = mid - 1; + } else left = mid + 1; + } + if (ans == -1) return NaN; + return ans; +} + + function sex_tuples(array) { + let len = array.length; + let lhs = []; + let rhs = []; + for(let i = 0; i < len; i++) { + for(let j = 0; j < len; j++) { + for(let k = 0; k < len; k++) { + lhs.push( array[i] * array[j] + array[k] ); + } + } + } + for(let i = 0; i < len; i++) { + if(array[i] == 0) continue; + for(let j = 0; j < len; j++) { + for(let k = 0; k < len; k++) { + rhs.push( array[i] * (array[j] + array[k]) ); + } + } + } + + rhs.sort( (a, b) => a - b); + let ans = 0; + for(let i = 0; i < lhs.length; i++) { + let lb = lower_bound(rhs, lhs[i]); + let ub = upper_bound(rhs, lhs[i]); + ans += (ub - lb); + } + return ans; +} +console.log(sex_tuples([2, 3])); + diff --git a/Javascript-DSA/Searching/sqrt.js b/Javascript-DSA/Searching/sqrt.js new file mode 100644 index 00000000..1ad9f3c4 --- /dev/null +++ b/Javascript-DSA/Searching/sqrt.js @@ -0,0 +1,19 @@ +function sqrt(target) { + if(target == 10 || target == 1) return target; + if(target < 0) return NaN; + let low = 1; + let high = target - 1; + while(low <= high) { + let mid = low + Math.floor( (high - low) / 2); + if(mid * mid == target) return mid; + if(mid * mid < target) { + //? it can be a possible answer otherwise a better ans can be to the right. + ans = mid; + low = mid + 1; + } else { + high = mid - 1; + } + } + return ans; +} +console.log(sqrt(50)); \ No newline at end of file diff --git a/Javascript-DSA/Searching/string_matching.js b/Javascript-DSA/Searching/string_matching.js new file mode 100644 index 00000000..51fe9668 --- /dev/null +++ b/Javascript-DSA/Searching/string_matching.js @@ -0,0 +1,18 @@ +//! brute force or Naive approach +//! time O((m - n + 1)*n) --> O(m*n) | space O(1) +function string_matching_naive(s, p) { + let m = s.length; + let n = p.length; + for(let i = 0; i <= (m - n); i++) { + let flag = true; + for(let j = 0; j < n; j++) { + if(s[i + j] != p[j]) { + flag = false; + break; + } + } + if(flag) console.log(i); + } +} + +string_matching_naive("aabbabcbbaabcab", "abc"); \ No newline at end of file diff --git a/Javascript-DSA/Searching/tempCodeRunnerFile.js b/Javascript-DSA/Searching/tempCodeRunnerFile.js new file mode 100644 index 00000000..9501358c --- /dev/null +++ b/Javascript-DSA/Searching/tempCodeRunnerFile.js @@ -0,0 +1 @@ +Math.floor(m / w) / Math.floor(w * h) \ No newline at end of file diff --git a/Javascript-DSA/Searching/upperBound.js b/Javascript-DSA/Searching/upperBound.js new file mode 100644 index 00000000..21d95e91 --- /dev/null +++ b/Javascript-DSA/Searching/upperBound.js @@ -0,0 +1,23 @@ +//! Given a sorted Array and a element x, find the first element +//! element in the array that greater than x. + +function upperBound(array, target) { + let l = 0; + let r = array.length - 1; + let ans = -1; + while(l <= r) { + let mid = Math.floor( (l + r) / 2); + if(array[mid] > target) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + if(ans == -1) return NaN; //! if every element < target + return ans; +} +let array = [1, 2, 2, 3, 3, 4, 6, 7]; +let target = 5; + +console.log(upperBound(array, target)); + + diff --git a/Javascript-DSA/Sorting/.DS_Store b/Javascript-DSA/Sorting/.DS_Store new file mode 100644 index 00000000..c3d99512 Binary files /dev/null and b/Javascript-DSA/Sorting/.DS_Store differ diff --git a/Javascript-DSA/Sorting/AlgoExpert/.DS_Store b/Javascript-DSA/Sorting/AlgoExpert/.DS_Store new file mode 100644 index 00000000..a41445f4 Binary files /dev/null and b/Javascript-DSA/Sorting/AlgoExpert/.DS_Store differ diff --git a/Javascript-DSA/Sorting/AlgoExpert/bubble_sort.js b/Javascript-DSA/Sorting/AlgoExpert/bubble_sort.js new file mode 100644 index 00000000..2402f2d4 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/bubble_sort.js @@ -0,0 +1,26 @@ +//! worst-case: O(n^2) time | O(1) space +//! avg-case: O(n^2) time | O(1) space +//! best-case: O(n) time | O(1) space + +function bubbleSort(array) { + let isSorted = false; + let counter = 0; + while(!isSorted) { + isSorted = true; + for(let i = 0; i < array.length - 1 - counter; i++) { + if(array[i] > array[i + 1]) { + swap(i, i + 1, array); + isSorted = false; + } + } + counter++; + } + return array; +} +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + + +let array = [8, -6, 7, 10, 8, -1, 6, 2, 4, -5, 1, 10, 8, -10, -9, -10, 8, 9, -2, 7, -2, 4]; +console.log(bubbleSort(array)); \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/bucketSort.js b/Javascript-DSA/Sorting/AlgoExpert/bucketSort.js new file mode 100644 index 00000000..273955f2 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/bucketSort.js @@ -0,0 +1,20 @@ +// ! O(n) time | O(1) | space modified bucket sort +function three_number_sort(array, order) { + const valueCounts = [0, 0, 0]; + for(const element of array) { + const orderIdx = order.indexOf(element); + valueCounts[orderIdx]++; + } + for(let idx = 0; idx < 3; idx++) { + const value = order[idx]; + const count = valueCounts[idx]; + + const numElementsBefore = valueCounts.slice(0, idx).reduce((a, b) => a + b, 0); + + for(let n = 0; n < count; n++) { + const currentIdx = numElementsBefore + n; + array[currentIdx] = value; + } + } + return array; +} \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/dummy.js b/Javascript-DSA/Sorting/AlgoExpert/dummy.js new file mode 100644 index 00000000..b6da92dc --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/dummy.js @@ -0,0 +1,48 @@ +function mergeSort(array) { + mergeSortHelper(array, 0, array.length - 1); + return array; +} + +function mergeSortHelper(array, startIdx, endIdx) { + if(startIdx == endIdx) return; + const midIdx = Math.floor((startIdx + endIdx) / 2); + mergeSortHelper(array, startIdx, midIdx); + mergeSortHelper(array, midIdx + 1, endIdx); + doMerge(array, startIdx, midIdx, midIdx + 1, endIdx); +} + +function doMerge(array, leftStartIdx, leftEndIdx, rightStartIdx, rightEndIdx) { + let leftLength = leftEndIdx - leftStartIdx; + let rightLength = rightEndIdx - rightStartIdx; + + let arr1 = new Array(leftLength); + let arr2 = new Array(rightLength); + + for(let i = 0; i <= leftLength; i++) { + arr1[i] = array[leftStartIdx + i]; + } + + for(let i = 0; i <= rightLength; i++) { + arr2[i] = array[rightStartIdx + i]; + } + + let i = 0; + let j = 0; + let k = leftStartIdx; + + while(i < arr1.length && j < arr2.length) { + if(arr1[i] < arr2[j]) { + array[k++] = arr1[i++]; + } else { + array[k++] = arr2[j++]; + } + } + + while(i < arr1.length) { + array[k++] = arr1[i++]; + } + + while(j < arr2.length) { + array[k++] = arr2[j++]; + } +} \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/heapSort/continuous_median.js b/Javascript-DSA/Sorting/AlgoExpert/heapSort/continuous_median.js new file mode 100644 index 00000000..446dcb12 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/heapSort/continuous_median.js @@ -0,0 +1,116 @@ +class ContinuousMedianHandler { + constructor() { + this.lowers = new Heap(MAX_HEAP_FUNC, []); + this.greaters = new Heap(MIN_HEAP_FUNC, []); + this.median = null; + } + +//! O(logn) time | O(n) space + insert(number) { + if(!this.lowers.length || number < this.lowers.peek()){ + this.lowers.insert(number); + } else { + this.greaters.insert(number); + } + this.rebalanceHeaps(); + this.updateMedian(); + } + + rebalanceHeaps() { + if(this.lowers.length - this.greaters.length === 2) { + this.greaters.insert(this.lowers.remove()); + } else if(this.greaters.length - this.lowers.length === 2) { + this.lowers.insert(this.greaters.remove()); + } + } + updateMedian() { + if(this.lowers.length === this.greaters.length) { + this.median = (this.lowers.peek() + this.greaters.peek()) / 2; + } else if(this.lowers.length > this.greaters.length) { + this.median = this.lowers.peek(); + } else { + this.median = this.greaters.peek(); + } + } + getMedian() { + return this.median; + } +} +class Heap { + constructor(comparisonFunc, array) { + this.comparisonFunc = comparisonFunc; + this.heap = this.buildHeap(array); + this.length = this.heap.length; + } + + buildHeap(array) { + const firstParentIdx = Math.floor((array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx >= 0; currentIdx--) { + this.siftDown(currentIdx, array.length - 1, array); + } + return array; + } + siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(childOneIdx <= endIdx) { + const childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2 : -1; + let idxToSwap; + if(childTwoIdx !== -1) { + if(this.comparisonFunc(heap[childTwoIdx], heap[childOneIdx])) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + } else { + idxToSwap = childOneIdx; + } if(this.comparisonFunc(heap[idxToSwap], heap[currentIdx])) { + this.swap(currentIdx, idxToSwap, heap); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + } + } + siftUp(currentIdx, heap) { + let parentIdx = Math.floor((currentIdx - 1) / 2); + while(currentIdx > 0) { + if(this.comparisonFunc(heap[currentIdx], heap[parentIdx])) { + this.swap(currentIdx, parentIdx, heap); + currentIdx = parentIdx; + parentIdx = Math.floor((currentIdx - 1) / 2); + } else { + return; + } + } + } + + peek() { + return this.heap[0]; + } + + remove() { + this.swap(0, this.length - 1, this.heap); + const valueToRemove = this.heap.pop(); + this.length--; + this.siftDown(0, this.length - 1, this.heap); + return valueToRemove; + } + + insert(value) { + this.heap.push(value); + this.length++; + this.siftUp(this.length - 1, this.heap); + } + + swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; + } +} + +function MAX_HEAP_FUNC(a, b) { + return a > b; +} +function MIN_HEAP_FUNC(a, b) { + return a < b; +} \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/heapSort/heapsort.js b/Javascript-DSA/Sorting/AlgoExpert/heapSort/heapsort.js new file mode 100644 index 00000000..b6023a9b --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/heapSort/heapsort.js @@ -0,0 +1,47 @@ +//! Best: O(nlogn) time | O(1) space +//! Best: O(nlogn) time | O(1) space +//! Worst: O(nlogn) time | O(1) space + +function heapSort(array) { + buildMaxHeap(array); + for(let endIdx = array.length - 1; endIdx > -1; endIdx--) { + swap(0, endIdx, array); + siftDown(0, endIdx - 1, array); + } + return array; +} + +function buildMaxHeap(array) { + let firstParentIdx = Math.floor((array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx > -1; currentIdx--) { + siftDown(currentIdx, array.length - 1, array); + } +} + +function siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(childOneIdx <= endIdx) { + let childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2 : -1; + let idxToSwap; + if(childTwoIdx != -1 && heap[childTwoIdx] > heap[childOneIdx]) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + if(heap[idxToSwap] > heap[currentIdx]) { + swap(idxToSwap, currentIdx, array); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + } +} + +function swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; +} + + +let array = [48, 12, 24, 7, 8, -5, 24, 391, 24, 56, 2, 6, 8, 41]; +console.log(heapSort(array)); \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/heapSort/minHeap.js b/Javascript-DSA/Sorting/AlgoExpert/heapSort/minHeap.js new file mode 100644 index 00000000..cb935407 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/heapSort/minHeap.js @@ -0,0 +1,65 @@ +class MinHeap { + constructor(array) { + this.heap = this.buildHeap(array); + } + //! O(n) time | O(1) space + buildHeap(array) { + const firstParentIdx = Math.floor((array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx > -1; currentIdx--) { + this.siftDown(currentIdx, array.length - 1, array); + } + } + //! O(logn) time | O(1) space + siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(currentIdx <= endIdx) { + const childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2: -1; + let idxToSwap; + if(childTwoIdx != -1 && heap[childTwoIdx] < heap[childOneIdx]) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + if(heap[idxToSwap] < heap[currentIdx]) { + this.swap(idxToSwap, currentIdx, heap); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + + }; + } + //! O(logn) time | O(1) space + siftUp(currentIdx, heap) { + let parentIdx = Math.floor( (currentIdx - 1) / 2 ); + while(currentIdx > 0 && heap[currentIdx] < heap[parentIdx]) { + this.swap(currentIdx, parentIdx, heap); + currentIdx = parentIdx; + parentIdx = Math.floor( (currentIdx - 1) / 2 ); + } + } + //! O(1) time | O(1) space + peek() { + return this.heap[0]; + } + //! O(logn) time | O(1) space + remove() { + this.swap(0, this.heap,length - 1, this.heap); + const valueToRemove = this.heap.pop(); + this.siftDown(0, this.heap.length - 1, this.heap); + return valueToRemove; + } + //! O(logn) time | O(1) space + insert(value) { + this.heap.push(value); + this.siftUp(this.heap.length - 1, this.heap); + } + //! O(1) time | O(1) space + swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; + } +} + +let array = [48, 12, 24, 7, 8, -5, 24, 391, 24, 56, 2, 6, 8, 41]; +const heap = new MinHeap(array); \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/heapSort/sort_ksorted_arrays.js b/Javascript-DSA/Sorting/AlgoExpert/heapSort/sort_ksorted_arrays.js new file mode 100644 index 00000000..b0a79505 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/heapSort/sort_ksorted_arrays.js @@ -0,0 +1,87 @@ +//! O(nlog(k)) time | O(k) space - where n is the number of elements +//! in the array and k is how far away elements are from their sorted position. + +function sortKSortedArray(array, k) { + + const minHeapWithElements = new MinHeap(array.slice(0, Math.min(k + 1, array.length))); + + let nextIndexToInsertElement = 0; + for(let idx = k + 1; idx < array.length; idx++) { + const minElement = minHeapWithElements.remove(); + array[nextIndexToInsertElement] = minElement; + nextIndexToInsertElement++; + + const currentElement = array[idx]; + minHeapWithElements.insert(currentElement); + } + while(!minHeapWithElements.isEmpty()) { + const minElement = minHeapWithElements.remove(); + array[nextIndexToInsertElement] = minElement; + nextIndexToInsertElement++; + } + + return array; + } +class MinHeap { + constructor(array) { + this.heap = this.buildHeap(array); + } + isEmpty() { + return this.heap.length === 0; + } + buildHeap(array) { + const firstParentIdx = Math.floor( (array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx >= 0; currentIdx--) { + this.siftDown(currentIdx, array.length - 1, array); + } + return array; + } + siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(childOneIdx <= endIdx) { + const childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2 : -1; + let idxToSwap; + if(childTwoIdx !== -1 && heap[childTwoIdx] < heap[childOneIdx]) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + if(heap[idxToSwap] < heap[currentIdx]) { + this.swap(currentIdx, idxToSwap, heap); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + } + } + + siftUp(currentIdx, heap) { + let parentIdx = Math.floor((currentIdx - 1) / 2); + while(currentIdx > 0 && heap[currentIdx] < heap[parentIdx]) { + this.swap(currentIdx, parentIdx, heap); + currentIdx = parentIdx; + parentIdx = Math.floor( (currentIdx - 1) / 2); + } + } + peek() { + return this.heap[0]; + } + remove() { + this.swap(0, this.heap.length - 1, this.heap); + const valueToRemove = this.heap.pop(); + this.siftDown(0, this.heap.length - 1, this.heap); + return valueToRemove; + } + insert(value) { + this.heap.push(value); + this.siftUp(this.heap.length - 1, this.heap); + } + swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; + } +} + +let arr = [3, 2, 1, 5, 4, 7, 6, 5]; +let k = 3; +console.log(sortKSortedArray(arr, k)); \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/insertion_sort.js b/Javascript-DSA/Sorting/AlgoExpert/insertion_sort.js new file mode 100644 index 00000000..3acb2908 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/insertion_sort.js @@ -0,0 +1,23 @@ +//! worst-case: O(n^2) time | O(1) space +//! avg-case: O(n^2) time | O(1) space +//! best-case: O(n) time | O(1) space + +function insertionSort(array) { + for(let i = 1; i < array.length; i++) { + let j = i; + while( j > 0 && array[j] < array[j - 1] ) { + swap(j, j - 1, array); + j -= 1; + } + } + return array; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +let array = [8, -6, 7, 10, 8, -1, 6, 2, 4, -5, 1, 10, 8, -10, -9, -10, 8, 9, -2, 7, -2, 4]; + +console.log(insertionSort(array)); + \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/mergeSort/countInversions.js b/Javascript-DSA/Sorting/AlgoExpert/mergeSort/countInversions.js new file mode 100644 index 00000000..a8d6df10 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/mergeSort/countInversions.js @@ -0,0 +1,52 @@ +function countInversions(array) { + return countInversionsHelper(array, 0, array.length - 1); +} +function countInversionsHelper(array, startIdx, endIdx) { + if(startIdx >= endIdx) return 0; + let midIdx = Math.floor((startIdx + endIdx) / 2); + let leftInversions = countInversionsHelper(array, startIdx, midIdx); + let rightInversions = countInversionsHelper(array, midIdx + 1, endIdx); + let mergedInversions = mergeAndCountInversions(array, startIdx, midIdx, midIdx + 1, endIdx); + return leftInversions + rightInversions + mergedInversions; +} +function mergeAndCountInversions(array, leftStartIdx, leftEndIdx, rightStartIdx, rightEndIdx) { + let inversions = 0; + let leftArrLength = leftEndIdx - leftStartIdx + 1; + let rightArrLength = rightEndIdx - rightStartIdx + 1; + + let arr1 = new Array(leftArrLength); + let arr2 = new Array(rightArrLength); + + for(let i = 0; i < leftArrLength; i++) { + arr1[i] = array[leftStartIdx + i]; + } + for(let i = 0; i < rightArrLength; i++) { + arr2[i] = array[rightStartIdx + i]; + } + + let i = 0; + let j = 0; + let k = leftStartIdx; + + while(i < leftArrLength && j < rightArrLength) { + if(arr1[i] <= arr2[j]) { + array[k++] = arr1[i++]; + }else { + inversions += leftArrLength - i; + array[k++] = arr2[j++]; + } + } + + while(i < leftArrLength) { + array[k++] = arr1[i++]; + } + while(j < rightArrLength) { + array[k++] = arr2[j++]; + } + + return inversions; +} + +let array = [2, 3, 3, 1, 9, 5, 6]; + +console.log(countInversions(array)); diff --git a/Javascript-DSA/Sorting/AlgoExpert/mergeSort/mergeSort.js b/Javascript-DSA/Sorting/AlgoExpert/mergeSort/mergeSort.js new file mode 100644 index 00000000..919ef2b4 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/mergeSort/mergeSort.js @@ -0,0 +1,45 @@ +//! every case O(nlogn) time | O(n) space + +function mergeSort(array) { + mergeSortHelper(array, 0, array.length - 1); + return array; +} +function mergeSortHelper(array, startIdx, endIdx) { + if (startIdx == endIdx) return; + const midIdx = Math.floor(startIdx + (endIdx - startIdx) / 2); + mergeSortHelper(array, startIdx, midIdx); + mergeSortHelper(array, midIdx + 1, endIdx); + doMerge(array, startIdx, midIdx, midIdx + 1, endIdx); +} +function doMerge(array, leftStartIdx, leftEndIdx, rightStartIdx, rightEndIdx) { + let leftSubArrLen = leftEndIdx - leftStartIdx + 1; + let rightSubArrLen = rightEndIdx - rightStartIdx + 1; + + let leftSubArr = new Array(leftSubArrLen); + let rightSubArr = new Array(rightSubArrLen); + + for (let i = 0; i < leftSubArrLen; i++) + leftSubArr[i] = array[leftStartIdx + i]; + + for (let i = 0; i < rightSubArrLen; i++) + rightSubArr[i] = array[rightStartIdx + i]; + + let i = 0; + let j = 0; + let k = leftStartIdx; + + while (i < leftSubArrLen && j < rightSubArrLen) { + if (leftSubArr[i] < rightSubArr[j]) array[k++] = leftSubArr[i++]; + else array[k++] = rightSubArr[j++]; + } + while (i < leftSubArrLen) array[k++] = leftSubArr[i++]; + while (j < rightSubArrLen) array[k++] = rightSubArr[j++]; + return; +} + +let array = [ + 2, -2, -6, -10, 10, 4, -8, -1, -8, -4, 7, -4, 0, 9, -9, 0, -9, -9, 8, 1, -4, + 4, 8, 5, 1, 5, 0, 0, 2, -10, +]; + +console.log(mergeSort(array)); diff --git a/Javascript-DSA/Sorting/AlgoExpert/quickSort/modified_quick_sort.js b/Javascript-DSA/Sorting/AlgoExpert/quickSort/modified_quick_sort.js new file mode 100644 index 00000000..769ea9e9 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/quickSort/modified_quick_sort.js @@ -0,0 +1,45 @@ + +//! best/avg case O(nlogn) time | O(logn) space +//! worst case O(n^2) time | O(logn) space +//! inplace algorithm +function quickSort(array) { + quickSortHelper(array, 0, array.length - 1); + return array; +} + +function quickSortHelper(array, startIdx, endIdx) { + while(startIdx <= endIdx) { + if(startIdx == endIdx) return array[startIdx]; + else { + let m = partition(array, startIdx, endIdx); + if((m - startIdx) < (endIdx - m)) { + quickSortHelper(array, startIdx, m - 1); + startIdx = m + 1; + } else { + quickSortHelper(array, m + 1, endIdx); + endIdx = m - 1; + } + } + } +} + +function partition(array, leftIdx, rightIdx) { + let i = leftIdx; + let pivot = array[i]; + for(let j = i + 1; j <= rightIdx; j++) { + if(array[j] < pivot) { + i++; + swap(i, j, array); + } + } + swap(leftIdx, i, array); + return i; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +const array = [8, 5, 2, 9, 5, 6, 3]; + +console.log(quickSort(array)); \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/quickSort/quick_sort.js b/Javascript-DSA/Sorting/AlgoExpert/quickSort/quick_sort.js new file mode 100644 index 00000000..6e4915d8 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/quickSort/quick_sort.js @@ -0,0 +1,38 @@ + +//! best/avg case O(nlogn) time | O(logn) space +//! worst case O(n^2) time | O(n) space + +function quickSort(array) { + quickSortHelper(array, 0, array.length - 1); + return array; +} + +function quickSortHelper(array, startIdx, endIdx) { + if(startIdx >= endIdx) return; + else { + let m = partition(array, startIdx, endIdx); + quickSortHelper(array, startIdx, m - 1); + quickSortHelper(array, m + 1, endIdx); + } +} + +function partition(array, leftIdx, rightIdx) { + let i = leftIdx; + let pivot = array[i]; + for(let j = i + 1; j <= rightIdx; j++) { + if(array[j] < pivot) { + i++; + swap(i, j, array); + } + } + swap(leftIdx, i, array); + return i; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +const array = [8, 5, 2, 9, 5, 6, 3]; + +console.log(quickSort(array)); \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/selection_sort.js b/Javascript-DSA/Sorting/AlgoExpert/selection_sort.js new file mode 100644 index 00000000..d9806c24 --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/selection_sort.js @@ -0,0 +1,23 @@ +//! worst-case: O(n^2) time | O(1) space +//! avg-case: O(n^2) time | O(1) space +//! best-case: O(n^2) time | O(1) space + +function selectionSort(array) { + let startIdx = 0; + while(startIdx < array.length - 1) { + let smallestIdx = startIdx; + for(let i = startIdx + 1; i < array.length; i++) { + if(array[smallestIdx] > array[i]) smallestIdx = i; + } + swap(startIdx, smallestIdx, array); + startIdx++; + } + return array; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +let array = [8, -6, 7, 10, 8, -1, 6, 2, 4, -5, 1, 10, 8, -10, -9, -10, 8, 9, -2, 7, -2, 4]; +console.log(selectionSort(array)); \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/tempCodeRunnerFile.js b/Javascript-DSA/Sorting/AlgoExpert/tempCodeRunnerFile.js new file mode 100644 index 00000000..b6da92dc --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/tempCodeRunnerFile.js @@ -0,0 +1,48 @@ +function mergeSort(array) { + mergeSortHelper(array, 0, array.length - 1); + return array; +} + +function mergeSortHelper(array, startIdx, endIdx) { + if(startIdx == endIdx) return; + const midIdx = Math.floor((startIdx + endIdx) / 2); + mergeSortHelper(array, startIdx, midIdx); + mergeSortHelper(array, midIdx + 1, endIdx); + doMerge(array, startIdx, midIdx, midIdx + 1, endIdx); +} + +function doMerge(array, leftStartIdx, leftEndIdx, rightStartIdx, rightEndIdx) { + let leftLength = leftEndIdx - leftStartIdx; + let rightLength = rightEndIdx - rightStartIdx; + + let arr1 = new Array(leftLength); + let arr2 = new Array(rightLength); + + for(let i = 0; i <= leftLength; i++) { + arr1[i] = array[leftStartIdx + i]; + } + + for(let i = 0; i <= rightLength; i++) { + arr2[i] = array[rightStartIdx + i]; + } + + let i = 0; + let j = 0; + let k = leftStartIdx; + + while(i < arr1.length && j < arr2.length) { + if(arr1[i] < arr2[j]) { + array[k++] = arr1[i++]; + } else { + array[k++] = arr2[j++]; + } + } + + while(i < arr1.length) { + array[k++] = arr1[i++]; + } + + while(j < arr2.length) { + array[k++] = arr2[j++]; + } +} \ No newline at end of file diff --git a/Javascript-DSA/Sorting/AlgoExpert/three_number_sort.js b/Javascript-DSA/Sorting/AlgoExpert/three_number_sort.js new file mode 100644 index 00000000..c010b22f --- /dev/null +++ b/Javascript-DSA/Sorting/AlgoExpert/three_number_sort.js @@ -0,0 +1,86 @@ +// ! O(n) time | O(1) space +function three_number_sort(array, order) { + let firstValue = array[0]; + let secondValue = array[1]; + + let firstIdx = 0; + let secondIdx = 0; + let thirdIdx = array.length - 1; + + while(secondIdx <= thirdIdx) { + const value = array[secondIdx]; + if(value == firstValue) { + swap(firstIdx, secondIdx, array); + firstIdx++; + secondIdx++; + } else if(value == secondValue) { + secondIdx++; + } else { + swap(secondIdx, thirdIdx, array); + thirdIdx--; + } + } + return array; + +} + + + + + + + + + +// ! O(n) time | O(1) space +function three_number_sort(array, order) { + const firstValue = order[0]; + const thirdValue = order[2]; + + let firstIdx = 0; + for(let i = 0; i < array.length; i++) { + if(array[i] === firstValue) { + swap(i, firstIdx, array); + firstIdx++; + } + } + + let thirdIdx = array.length - 1; + for(let i = array.length - 1; i > -1; i--) { + if(array[i] === thirdValue) { + swap(i, thirdIdx, array); + thirdIdx--; + } + } + return array; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +// ! O(n) time | O(1) | space modified bucket sort +function three_number_sort(array, order) { + const valueCounts = [0, 0, 0]; + for(const element of array) { + const orderIdx = order.indexOf(element); + valueCounts[orderIdx]++; + } + for(let idx = 0; idx < 3; idx++) { + const value = order[idx]; + const count = valueCounts[idx]; + + const numElementsBefore = valueCounts.slice(0, idx).reduce((a, b) => a + b, 0); + + for(let n = 0; n < count; n++) { + const currentIdx = numElementsBefore + n; + array[currentIdx] = value; + } + } + return array; +} + + +let array = [1, 0, 0, -1, -1, 0, 1, 1]; +const order = [0, 1, -1]; +console.log(three_number_sort(array, order)); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/.DS_Store b/Javascript-DSA/Stacks/.DS_Store new file mode 100644 index 00000000..c3d99512 Binary files /dev/null and b/Javascript-DSA/Stacks/.DS_Store differ diff --git a/Javascript-DSA/Stacks/AlgoExpert/balancedBrackets.js b/Javascript-DSA/Stacks/AlgoExpert/balancedBrackets.js new file mode 100644 index 00000000..3c7432c3 --- /dev/null +++ b/Javascript-DSA/Stacks/AlgoExpert/balancedBrackets.js @@ -0,0 +1,26 @@ +//! O(n) time | O(n) space +function balancedBrackets(string) { + + const openingBrackets = '([{'; + const closingBrackets = ')]}'; + const matchingBrackets = { ')': '(', ']': '[', '}': '{'}; + const stack = []; + + for(const char of string) { + if(openingBrackets.includes(char)) { + stack.push(char); + } else if(closingBrackets.includes(char)) { + if(stack.length == 0) return false; + if(stack[stack.length - 1] == matchingBrackets[char]) { + stack.pop(); + } else { + return false; + } + } + } + return stack.length == 0; +} + +const string = "([])(){}(())()()"; + +console.log(balancedBrackets(string)); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/AlgoExpert/minMaxStackConstruction.js b/Javascript-DSA/Stacks/AlgoExpert/minMaxStackConstruction.js new file mode 100644 index 00000000..c17e149e --- /dev/null +++ b/Javascript-DSA/Stacks/AlgoExpert/minMaxStackConstruction.js @@ -0,0 +1,36 @@ +class minMaxStack { + constructor() { + this.minMaxStack = []; + this.stack = []; + } + //! O(1) time | O(1) space + peek() { + return this.stack[this.stack.length - 1]; + } + //! O(1) time | O(1) space + pop() { + this.minMaxStack.pop(); + return this.stack.pop(); + } + //! O(1) time | O(1) space + push(number) { + const newMinMax = {min: number, max: number}; + + if(this.minMaxStack.length) { + const lastMinMax = this.minMaxStack[this.minMaxStack.length - 1]; + newMinMax.min = Math.min(lastMinMax.min, number); + newMinMax.min = Math.max(lastMinMax.max, number); + } + this.minMaxStack.push(newMinMax); + this.stack.push(number); + } + //! O(1) time | O(1) space + getMin() { + return this.minMaxStack[this.minMaxStack.length - 1].min; + } + //! O(1) time | O(1) space + getMax() { + return this.maxMaxStack[this.maxMaxStack.length - 1].max; + } + +} \ No newline at end of file diff --git a/Javascript-DSA/Stacks/AlgoExpert/nextGreaterElement.js b/Javascript-DSA/Stacks/AlgoExpert/nextGreaterElement.js new file mode 100644 index 00000000..77af7228 --- /dev/null +++ b/Javascript-DSA/Stacks/AlgoExpert/nextGreaterElement.js @@ -0,0 +1,48 @@ +//! O(n) time | O(n) space +function nextGreaterElement(array) { + const result = new Array(array.length).fill(-1); + const stack = []; + + for(let idx = 2 * array.length - 1; idx > -1; idx--) { + + const circularIdx = idx % array.length; + while(stack.length > 0) { + if(stack[stack.length - 1] <= array[circularIdx]) { + stack.pop(); + } else { + result[circularIdx] = stack[stack.length - 1]; + break; + } + } + stack.push(array[circularIdx]); + } + return result; +} + +// function nextGreaterElement(arr) { +// let n = arr.length; +// let array = Array(2 * n); +// let result = []; +// for(let i = 0; i < arr.length; i++) { +// result[i] = -1; +// } +// for(let i = 0; i < arr.length; i++) { +// array[i] = array[n + i] = arr[i]; +// } +// for(let i = 0; i < arr.length; i++) { +// let j = i + 1; +// while(j < arr.length + i + 1) { +// if(array[j] > array[i]) { +// result[i] = array[j]; +// break; +// } +// j++; +// } +// } +// return result; +// } + + +const array = [2, 5, -3, -4, 6, 7, 2]; + +console.log(nextGreaterElement(array)) \ No newline at end of file diff --git a/Javascript-DSA/Stacks/AlgoExpert/sortStack.js b/Javascript-DSA/Stacks/AlgoExpert/sortStack.js new file mode 100644 index 00000000..db29ef35 --- /dev/null +++ b/Javascript-DSA/Stacks/AlgoExpert/sortStack.js @@ -0,0 +1,26 @@ +//! O(n^2) time | O(n) space + +function sortStack(stack) { + if(stack.length == 0) return stack; + + const top = stack.pop(); + + sortStack(stack); + + insertInSortedOrder(stack, top); + return stack; +} + +function insertInSortedOrder(stack, top) { + + if(stack.length == 0 || stack[stack.length - 1] <= top) { + stack.push(top); + return; + } + + const top = stack.pop(); + + insertInSortedOrder(stack, top) + + stack.push(top); +} \ No newline at end of file diff --git a/Javascript-DSA/Stacks/AlgoExpert/sunsetViews.js b/Javascript-DSA/Stacks/AlgoExpert/sunsetViews.js new file mode 100644 index 00000000..9fbcd2e1 --- /dev/null +++ b/Javascript-DSA/Stacks/AlgoExpert/sunsetViews.js @@ -0,0 +1,26 @@ +//! O(n) time | O(n) space + +function sunsetViews(buildings, direction) { + const buildingsWithSunsetViews = []; + + const startIdx = direction == 'WEST' ? 0: buildings.length - 1; + const step = direction == 'WEST' ? 1 : -1; + + let idx = startIdx; + let runningMaxHeight = 0; + while(idx > -1 && idx < buildings.length) { + const buildingHeight = buildings[idx]; + + if(buildingHeight > runningMaxHeight) { + buildingsWithSunsetViews.push(idx); + } + runningMaxHeight = Math.max(runningMaxHeight, buildingHeight); + + idx = idx + step; + } + + if(direction == 'EAST') buildingsWithSunsetViews.reverse(); + + return buildingsWithSunsetViews; + +} \ No newline at end of file diff --git a/Javascript-DSA/Stacks/dummy.js b/Javascript-DSA/Stacks/dummy.js new file mode 100644 index 00000000..5fa807b0 --- /dev/null +++ b/Javascript-DSA/Stacks/dummy.js @@ -0,0 +1,44 @@ +function a(arr) { + + let n = arr.length; + let array = Array(2 * n); + let result = []; + + + for(let i = 0; i < n; i++) { + result[i] = -1; + } + + for(let i = 0; i < arr.length; i++) { + array[i] = array[n + i] = arr[i]; + } + + + for(let i = 0; i < arr.length; i++) { + let j = i + 1; + while(j < arr.length + i) { + if(array[j] > array[i]) { + // result.splice(i, 0, array[j]); + result[i] = array[j]; + break; + } + j++; + } + // if(j == arr.length + i + 1 && array[j] < array[i]) + + // { + // // console.log("j", j); + // // console.log("i", i); + // result.splice(i, 0, -1); + // } +} + +return result; +} + + +let arr = [2, 5, -3, -4, 6, 7, 2]; +// let arr = [1, 0, 1, 0, 1, 0, 1]; + +console.log(a(arr)); +// a(arr); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/insertAtBottom.js b/Javascript-DSA/Stacks/insertAtBottom.js new file mode 100644 index 00000000..4b3457bb --- /dev/null +++ b/Javascript-DSA/Stacks/insertAtBottom.js @@ -0,0 +1,79 @@ +//! 07/02/2022 + +class Stack { + constructor() { + this.top = 0; + this.data = []; + } + + push(element) { + this.data[this.top] = element; + this.top = this.top + 1; + } + + isEmpty() { + return this.top == 0; + } + pop() { + if(this.isEmpty()) { + console.log("stack is underflow"); + return undefined; + } + this.top = this.top - 1; + return this.data.pop(); + } + //! top value + peek() { + if (this.isEmpty()) { + return undefined; + } + return this.data[this.top - 1]; + } +} + +const st = new Stack(); +st.push(100); +st.push(200); +st.push(300); +st.push(400); +st.push(500); +st.push(600); +st.push(700); +st.push(800); + +/** + * ! 1. create an array and pop every element from stack and push into stack. + * + * ! 2. use bottom up approach. + */ + +function insertAtBottomIterative(stack, element) { + const secondary = new Stack(); + + while (!st.isEmpty()) { + secondary.push(st.pop()); + } + st.push(element); + + while (!secondary.isEmpty()) { + st.push(secondary.pop()); + } + +} + +function insertAtBottomRecursively(stack, element) { + if (st.isEmpty()) { + st.push(element); + return; + } + const topElement = stack.pop(); + insertAtBottomRecursively(st, element); + st.push(topElement); +} +// insertAtBottomIterative(st, 10); +insertAtBottomRecursively(st, 10); + +console.log(st.peek()); + +console.log(st); + diff --git a/Javascript-DSA/Stacks/matchingBrackets.js b/Javascript-DSA/Stacks/matchingBrackets.js new file mode 100644 index 00000000..72caef96 --- /dev/null +++ b/Javascript-DSA/Stacks/matchingBrackets.js @@ -0,0 +1,24 @@ +//! 07/02/2022 +function matchingBrackets(string) { + const openingBrackets = '({['; + const closingBrackets = ')}]'; + const matchingBrackets = { ')': '(', '}': '{', ']': '[' }; + + let stack = []; + + for(char of string) { + if(openingBrackets.includes(char)) { + stack.push(char); + } else if(closingBrackets.includes(char)) { + if(stack.length === 0) return false; + else if(stack[stack.length - 1] === matchingBrackets[char]) + stack.pop(); + } + } + return stack.length === 0; + } + + let string = '(({}}[]()))'; + + + console.log(matchingBrackets(string)); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/nextGreater.js b/Javascript-DSA/Stacks/nextGreater.js new file mode 100644 index 00000000..240c8f9e --- /dev/null +++ b/Javascript-DSA/Stacks/nextGreater.js @@ -0,0 +1,19 @@ +//! 08/02/2022 + +function nextGreater(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = 0; i < array.length; i++) { + while(stack.length > 0 && array[stack[stack.length - 1]] < array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result; +} + +let array = [2, 7, 3, 5, 4, 6, 8]; + +console.log(nextGreater(array)); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/nextMinMax.js b/Javascript-DSA/Stacks/nextMinMax.js new file mode 100644 index 00000000..04219a65 --- /dev/null +++ b/Javascript-DSA/Stacks/nextMinMax.js @@ -0,0 +1,49 @@ +class Stack { + constructor() { + this.minMaxStack = []; + this.stack = []; + } + + peek() { + return this.stack[stack.length - 1]; + } + + pop() { + this.minMaxStack.pop(); + return this.stack.pop(); + } + + push(number) { + const newMinMax = {min: number, max: number}; + + if(this.minMaxStack.length) { + const lastMinMax = this.minMaxStack[this.minMaxStack.length - 1]; + newMinMax.min = Math.min(lastMinMax.min, number); + newMinMax.max = Math.max(lastMinMax.max, number); + } + this.minMaxStack.push(newMinMax); + this.stack.push(number); + + } + + getMin() { + return this.minMaxStack[this.minMaxStack.length - 1].min; + } + + getMax() { + return this.minMaxStack[this.minMaxStack.length -1].max; + } +} + + +const stack = new Stack(); + +stack.push(5); +stack.push(2); +console.log(stack.getMin()); +console.log(stack.getMax()); +stack.push(7); + +console.log(stack.getMin()); +console.log(stack.getMax()); + diff --git a/Javascript-DSA/Stacks/nextSmaller.js b/Javascript-DSA/Stacks/nextSmaller.js new file mode 100644 index 00000000..820ffdd7 --- /dev/null +++ b/Javascript-DSA/Stacks/nextSmaller.js @@ -0,0 +1,20 @@ +//! 08/02/2022 +function nextSmaller(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = 0; i < array.length; i++) { + + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result; +} + +let array = [2, 7, 3, 5, 4, 6, 1]; + + +console.log(nextSmaller(array)); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/prevGreater.js b/Javascript-DSA/Stacks/prevGreater.js new file mode 100644 index 00000000..42fac664 --- /dev/null +++ b/Javascript-DSA/Stacks/prevGreater.js @@ -0,0 +1,23 @@ +//! 08/02/2022 +//! prevGreater is opposite of next smaller, just reverse given array and result array +function prevGreater(array) { + array.reverse(); + let result = new Array(array.length).fill(-1); + // const stack = new Stack(); + const stack = []; + + for(let i = 0; i < array.length; i++) { + + while(stack.length > 0 && array[stack[stack.length - 1]] < array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result.reverse(); +} + +let array = [2, 7, 3, 5, 4, 6, 1]; + + +console.log(prevGreater(array)); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/prevSmaller.js b/Javascript-DSA/Stacks/prevSmaller.js new file mode 100644 index 00000000..1ceed553 --- /dev/null +++ b/Javascript-DSA/Stacks/prevSmaller.js @@ -0,0 +1,18 @@ +//! 08/02/2022 +function prevSmaller(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = array.length - 1; i >= 0; i--) { + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result; +} + +let array = [2, 7, 3, 5, 4, 6, 1]; + +console.log(prevSmaller(array)); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/removeConsecutiveDuplicates.js.js b/Javascript-DSA/Stacks/removeConsecutiveDuplicates.js.js new file mode 100644 index 00000000..9159df6e --- /dev/null +++ b/Javascript-DSA/Stacks/removeConsecutiveDuplicates.js.js @@ -0,0 +1,49 @@ + +//! 07/02/2022 +class Stack { + constructor() { + this.top = -1; + this.data = []; + } + + push(element) { + this.top = this.top + 1; + this.data[this.top] = element; + } + isEmpty() { + return this.top == 0; + } + + removeConsecutiveDuplicates(arr) { + + for (let i = 0; i < arr.length; i++) { + if (this.data[this.top] !== arr[i]) + st.push(arr[i]); + } + +} + +} +let arr = [1, 2, 1, 1, 3, 3, 3, 3, 2, 1, 1]; + +const st = new Stack(); + +st.removeConsecutiveDuplicates(arr); + +function removeDuplicates(arr) { + + let prev = arr[0]; + let result = []; + result.push(prev); + + for (let i = 1; i < arr.length; i++) { + if (arr[i] !== prev) { + prev = arr[i]; + result.push(prev); + } + } + console.log(result); +} + +removeDuplicates(arr); + diff --git a/Javascript-DSA/Stacks/reverseStack.js b/Javascript-DSA/Stacks/reverseStack.js new file mode 100644 index 00000000..ba45afb7 --- /dev/null +++ b/Javascript-DSA/Stacks/reverseStack.js @@ -0,0 +1,71 @@ +//! 07/02/2022 +class Stack { + constructor() { + this.top = 0; + this.data = []; + } + + push(element) { + this.data[this.top] = element; + this.top = this.top + 1; + } + + isEmpty() { + return this.top == 0; + } + + pop() { + if(this.isEmpty()) { + console.log("stack is underflow"); + return undefined; + } + this.top = this.top - 1; + return this.data.pop(); + } + //! top value + peek() { + if (this.isEmpty()) { + return undefined; + } + return this.data[this.top - 1]; + } +} + +/** + * ! 1. create an array and pop every element from stack and push into stack. + * + * ! 2. use bottom up approach. + */ + +function insertAtBottomRecursively(stack, element) { + if (st.isEmpty()) { + st.push(element); + return; + } + const topElement = stack.pop(); + insertAtBottomRecursively(st, element); + st.push(topElement); +} + +function reverseStack(st) { + if(st.isEmpty()) return; + const topElement = st.pop(); + reverseStack(st); + insertAtBottomRecursively(st, topElement); +} + + +const st = new Stack(); +st.push(100); +st.push(200); +st.push(300); +st.push(400); +st.push(500); +st.push(600); +st.push(700); +st.push(800); + +reverseStack(st); + +console.log(st); + diff --git a/Javascript-DSA/Stacks/stack.js b/Javascript-DSA/Stacks/stack.js new file mode 100644 index 00000000..576d77a0 --- /dev/null +++ b/Javascript-DSA/Stacks/stack.js @@ -0,0 +1,45 @@ +//! 07/02/2022 +class Stack { + constructor() { + this.top = 0; + this.data = []; + } + + push(element) { + this.data[this.top] = element; + this.top = this.top + 1; + } + + isEmpty() { + return this.top == 0; + } + + pop() { + if(this.isEmpty()) { + console.log("stack is underflow"); + return undefined; + } + this.top = this.top - 1; + return this.data.pop(); + } + //! top value + peek() { + if (this.isEmpty()) { + return undefined; + } + return this.data[this.top - 1]; + } +} + +const st = new Stack(); +st.push(100); +st.push(200); +st.push(300); +st.push(400); +st.push(500); +st.push(600); + +console.log(st.peek()); +st.pop(); + +console.log(st.peek()); \ No newline at end of file diff --git a/Javascript-DSA/Stacks/stockSpan.js b/Javascript-DSA/Stacks/stockSpan.js new file mode 100644 index 00000000..6fa5cb45 --- /dev/null +++ b/Javascript-DSA/Stacks/stockSpan.js @@ -0,0 +1,29 @@ +//! 10/02/2022 + +function prevGreater(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = array.length - 1; i >= 0; i--) { + while(stack.length > 0 && array[stack[stack.length - 1]] < array[i]) { + const top = stack.pop(); + result[top] = i; + } + stack.push(i); + } + return result; +} + +function stockSpan(array) { + let result = []; + const prev = prevGreater(array); + for(let i = 0; i < array.length; i++) { + result[i] = i - prev[i]; + } + return result; +} + +let array = [31, 27, 14, 21, 30, 22]; + +console.log(stockSpan(array)); + diff --git a/Javascript-DSA/Stacks/tempCodeRunnerFile.js b/Javascript-DSA/Stacks/tempCodeRunnerFile.js new file mode 100644 index 00000000..8cc107da --- /dev/null +++ b/Javascript-DSA/Stacks/tempCodeRunnerFile.js @@ -0,0 +1,78 @@ +//! 07/02/2022 +class Stack { + constructor() { + this.top = 0; + this.data = []; + } + + push(element) { + this.data[this.top] = element; + this.top = this.top + 1; + } + + isEmpty() { + return this.top == 0; + } + + pop() { + if(this.isEmpty()) { + // console.log("stack is underflow"); + return undefined; + } + this.top = this.top - 1; + return this.data.pop(); + } + //! top value + peek() { + if (this.isEmpty()) { + return undefined; + } + return this.data[this.top - 1]; + } +} + +// function nextGreater(arr){ +// const st = new Stack(); +// st.push(0); +// let output = new Array(arr.length); +// for(let i = 1; i < arr.length; i++) { +// while(!st.isEmpty() && arr[st.peek()] < arr[i]) { +// output[st.peek()] = arr[i]; +// st.pop(); +// } +// st.push(i); +// } +// while(!st.isEmpty()) { +// output[st.peek()] = -1; +// st.pop(); +// } +// return output; +// } + +const st = new Stack(); + +// st.push(100); +// st.push(200); +// st.push(300); +// st.push(400); +// st.push(500); +// st.push(600); + + + +// console.log(nextGreater(arr)); + +function nextGreater(arr) { + const result = new Array(arr.length).fill(-1); + + for(let i = 0; i < arr.length; i++) { + + const stack = new Stack(); + console.log(stack.length); + + while(stack.length > 0) { + if(stack[stack.length - 1] <= arr[i]) { + stack.pop(); + } else { + result[i] = stack[stack.length - 1]; + console.log(result[i]); \ No newline at end of file diff --git a/Javascript-DSA/Strings/.DS_Store b/Javascript-DSA/Strings/.DS_Store new file mode 100644 index 00000000..c3d99512 Binary files /dev/null and b/Javascript-DSA/Strings/.DS_Store differ diff --git a/Javascript-DSA/Strings/AlgoExpert/ceaserCipherEncryptor.js b/Javascript-DSA/Strings/AlgoExpert/ceaserCipherEncryptor.js new file mode 100644 index 00000000..2d5a239d --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/ceaserCipherEncryptor.js @@ -0,0 +1,14 @@ +//! 0(n) time | O(n) space +function caesarCipherEncryptor(string, key) { + const newLetters = []; + const newKey = key % 26; + for(const letter of string) { + newLetters.push(getNewLetter(letter, newKey)); + } + return newLetters.join(''); +} + +function getNewLetter(letter, key) { + const newLetterCode = letter.charCodeAt() + key; + return newLetterCode <= 122 ? String.fromCharCode(newLetterCode) : String.fromCharCode(96 + (newLetterCode % 122)); +} \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/dummy.js b/Javascript-DSA/Strings/AlgoExpert/dummy.js new file mode 100644 index 00000000..176be127 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/dummy.js @@ -0,0 +1,7 @@ + +var a = 10; + +function b() { + console.log(a); +} +b(); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/firstNonRepeatingCharacter.js b/Javascript-DSA/Strings/AlgoExpert/firstNonRepeatingCharacter.js new file mode 100644 index 00000000..de78b0d7 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/firstNonRepeatingCharacter.js @@ -0,0 +1,46 @@ +//! O(n^2) time | O(1) space - where n is the length of the input string +function firstNonRepeatingCharacter(string) { + for(let i = 0; i < string.length; i++) { + let foundDuplicate = false; + for(let j = 0; j < string.length; j++) { + if(string[i] === string[j] && i !== j) foundDuplicate = true; + } + if(!foundDuplicate) return i; + } + return -1; +} + +//! O(n) time | O(1) space - where n is the length of the input string +//! The constant space is because the input string only has lowercase. +//! English-alphabet letters; thus our hash table will never have more than +//! 26 character frequencies. + +function firstNonRepeatingCharacter(string) { + const characterFrequencies = {}; + + for(const character of string) { + if( !(character in characterFrequencies)) characterFrequencies[character] = 0; + characterFrequencies[character]++; + } + +for(let i = 0; i < string.length; i++) { + const character = string[i]; + if(characterFrequencies[character] === 1) return i; +} +return -1; +} + +//! my logic +function firstNonRepeatingCharacter(string) { + let hash_table = {}; + for(const char of string) { + if ( !(char in hash_table)) hash_table[char] = 0; + + hash_table[char]++; + } + for( const [char, count] of Object.entries(hash_table)) { + if(count == 1) return string.indexOf(char); //! indexOf take O(n) time for finding index + } return -1; +} +const string = "abbccddcaff"; +console.log(firstNonRepeatingCharacter(string)); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/generateDocument.js b/Javascript-DSA/Strings/AlgoExpert/generateDocument.js new file mode 100644 index 00000000..893b01ec --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/generateDocument.js @@ -0,0 +1,71 @@ +//! O(n + m) time | O(c) space - where n is the number of characters, m is +//! ths length of the document, and c is the number of unique characters in the characters string. +function generateDocument(characters, document) { + const characterCounts = {}; + for(const character of characters) { + if(! (character in characterCounts)) characterCounts[character] = 0; + + characterCounts[character]++; + } + for(const character of document) { + if( !(character in characterCounts) || characterCounts[character] === 0) return false; + characterCounts[character]--; + } + return true; +} + + +//! O(m * (n + m)) time | O(1) space - where n is the number +//! of characters and m is the length of the document + +function generateDocument(characters, document) { +for(const character of document) { + const documentFrequency = countCharacterFrequency(character, document); + const charactersFrequency = countCharacterFrequency(character, characters); + if(documentFrequency > charactersFrequency) return false; +} + return true; +} + +function countCharacterFrequency(character, target) { + let frequency = 0; + for(const char of target) + if(char === character) frequency++; + return frequency; +} + + + +//! my logic, passed all test cases; +//! my logic O(n + m) time | O(c) space c is no of unique characters; +function generateDocument(characters, document) { + let hash_table = {}; + for(let i = 0; i < characters.length; i++) { + if(hash_table[characters[i]]) { + hash_table[characters[i]] += 1; + } else { + hash_table[characters[i]] = 1; + } + } + console.log(hash_table); + for(let i = 0; i < document.length; i++) { + if(!(document[i] in hash_table)) return false; + if(hash_table[document[i]] === 0) + return false; + hash_table[document[i]] -= 1; +} +console.log("------------------------"); +console.log(hash_table); + return true; +} + +let characters = "Bste!hetsi ogEAxpelrt x "; +let document = "AlgoExpert is the Best!"; + +let characters = "helloworld "; +let document = "hello wOrld"; + +let characters = "hello"; +let document = "wOrld"; + +console.log(generateDocument(characters, document)); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/groupAnagrams.js b/Javascript-DSA/Strings/AlgoExpert/groupAnagrams.js new file mode 100644 index 00000000..d52ac048 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/groupAnagrams.js @@ -0,0 +1,17 @@ + +// ! O(w * n * log(n)) time | O(wn) space - where w is the number of words and n is the length of the longest word +function groupAnagrams(words) { + const anagrams = {}; + for(const word of words) { + const sortedWord = word.split('').sort().join(''); + if(sortedWord in anagrams) { + anagrams[sortedWord].push(word); + } else { + anagrams[sortedWord] = [word]; + } + } + return Object.values(anagrams); +} +const words = ["yo", "act", "flop", "tac", "foo", "cat", "oy", "olfp"]; + +console.log(groupAnagrams(words)); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/longestPalindromeSubstring.js b/Javascript-DSA/Strings/AlgoExpert/longestPalindromeSubstring.js new file mode 100644 index 00000000..d5c79f01 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/longestPalindromeSubstring.js @@ -0,0 +1,39 @@ +//! O(n^2) time | O(1) space +function longestPalindromicSubstring(string) { + let currentLongest = [0, 1]; + for(let i = 1; i < string.length; i++) { + const odd = getLongestPalindromeFrom(string, i - 1, i + 1); + const even = getLongestPalindromeFrom(string, i - 1, i); + const longest = odd[1] - odd[0] > even[1] - even[0] ? odd : even; + currentLongest = currentLongest[1] - currentLongest[0] > longest[1] - longest[0] ? currentLongest : longest; + } + return string.slice(currentLongest[0], currentLongest[1]); +} +function getLongestPalindromeFrom(string, leftIdx, rightIdx) { + while(leftIdx >= 0 && rightIdx < string.length) { + if (string[leftIdx] != string[rightIdx]) break; + leftIdx--; + rightIdx++; + } + return [leftIdx + 1, rightIdx]; +} + +//! O(n^2) time | O(1) space +function longestPalindromicSubstring(string) { + let currentLongest = [0, 1]; + for(let i = 1; i < string.length; i++) { + const odd = getLongestPalindromeFrom(string, i - 1, i + 1); + const even = getLongestPalindromeFrom(string, i - 1, i); + const longest = odd[1] - odd[0] > even[1] - even[0] ? odd : even; + currentLongest = currentLongest[1] - currentLongest[0] > longest[1] - longest[0] ? currentLongest : longest; + } + return string.slice(currentLongest[0], currentLongest[1]); +} +function getLongestPalindromeFrom(string, leftIdx, rightIdx) { + while(leftIdx >= 0 && rightIdx < string.length) { + if (string[leftIdx] != string[rightIdx]) break; + leftIdx--; + rightIdx++; + } + return [leftIdx + 1, rightIdx]; +} \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/longestSubstringWithoutDuplicates.js b/Javascript-DSA/Strings/AlgoExpert/longestSubstringWithoutDuplicates.js new file mode 100644 index 00000000..3db0bc62 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/longestSubstringWithoutDuplicates.js @@ -0,0 +1,21 @@ +//! O(n) time | O(min(n, a)) space +function longestSubstringWithoutDuplication(string) { + const lastSeen = {}; + let longest = [0, 1]; + let startIdx = 0; + for(let i = 0; i < string.length; i++) { + const char = string[i]; + if(char in lastSeen) { + // startIdx = Math.max(startIdx, lastSeen[char] + 1); + startIdx = lastSeen[char] + 1; + console.log(startIdx) + } if(longest[1] - longest[0] < i + 1 - startIdx){ + longest = [startIdx, i+1]; + } + lastSeen[char] = i; + } + return string.slice(longest[0], longest[1]); + +} + +console.log(longestSubstringWithoutDuplication("clementisacap")) \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/minCharactersForWord.js b/Javascript-DSA/Strings/AlgoExpert/minCharactersForWord.js new file mode 100644 index 00000000..02cca421 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/minCharactersForWord.js @@ -0,0 +1,58 @@ +//! O(n * l) time | O(c) space - where n is the number of words, +//! l is the length of the longest word, and c is the +//! number of unique characters across all words. + + +function minimumCharactersForWords(words) { + const maximumCharacterFrequencies = {}; + + for(const word of words) { + const characterFrequencies = countCharacterFrequencies(word); + updateMaximumCharacterFrequencies(characterFrequencies, maximumCharacterFrequencies); + } + + return makeArrayFromCharacterFrequencies(maximumCharacterFrequencies); +} + +function countCharacterFrequencies(string) { + const characterFrequencies = {}; + + for(const character of string) { + if(!(character in characterFrequencies)) characterFrequencies[character] = 0; + characterFrequencies[character] += 1; + } + return characterFrequencies; +} + +function updateMaximumCharacterFrequencies(frequencies, maximumFrequencies) { + + for(const character in frequencies) { + const frequency = frequencies[character]; + + if(character in maximumFrequencies) maximumFrequencies[character] = Math.max(maximumFrequencies[character], frequency); + else { + maximumFrequencies[character] = frequency; + } + + + + } +} + + +function makeArrayFromCharacterFrequencies(characterFrequencies) { + const characters = []; + for(const character in characterFrequencies) { + + const frequency = characterFrequencies[character]; + + for(let i = 0; i < frequency; i++) { + characters.push(character); + } + } + return characters; +} + + +const words = ["this", "that", "did", "deed", "them!", "a"]; +console.log(minimumCharactersForWords(words)); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/palindromeCheck.js b/Javascript-DSA/Strings/AlgoExpert/palindromeCheck.js new file mode 100644 index 00000000..cbe71d32 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/palindromeCheck.js @@ -0,0 +1,37 @@ + + //! O(n^2) time | O(n) space +function isPalindrome(string) { + let reversedString = ''; + for(let i = string.length - 1; i >= 0; i) { + reversedString += string[i]; + } + return string === reversedString; +} + +//! O(n) time | O(n) space +function isPalindrome(string) { + + const reversedChars = []; + for(let i = string.length - 1; i >= 0; i--) { + reversedChars.push(string[i]); + } + return string === reversedChars.join(''); +} + +//! O(n) time | O(n) space +function isPalindrome(string, i = 0) { + const j = string.length - 1 - i; + return i >= j ? true : string[i] === string[j] && isPalindrome(string, i + 1); +} + +//!O(n) time | O(1) space +function isPalindrome(string) { + let i = 0; + let j = string.length - 1; + while(i < j) { + if(string[i] != string[j]) return false; + i++; + j--; + } + return true; +} \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/reverseWordsInString.js b/Javascript-DSA/Strings/AlgoExpert/reverseWordsInString.js new file mode 100644 index 00000000..4aec4c9a --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/reverseWordsInString.js @@ -0,0 +1,26 @@ +//! O(n) time | O(n) space +function reverseWordsInString(string) { + const characters = []; + for(const char of string) + characters.push(char); +console.log(characters); + + reverseListRange(characters, 0, characters.length - 1); + + console.log(characters); +} + +function reverseListRange(list, start, end) { + + while(start < end) { + const temp = list[start]; + list[start] = list[end]; + list[end] = temp; + start++; + end--; + } +} +const words = "AlgoExpert is the best!"; + + +console.log(reverseWordsInString(words)); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/runLengthEncoding.js b/Javascript-DSA/Strings/AlgoExpert/runLengthEncoding.js new file mode 100644 index 00000000..3bfa1e9c --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/runLengthEncoding.js @@ -0,0 +1,91 @@ +// function runLengthEncoding(string) { +// //!The input string is guaranteed to be non-empty, +// //! so first run will be of at least length 1. +// const encodedStringCharacters = []; +// let currentRunLength = 1; +// for(let i = 1; i < string.length; i++) { +// const currentCharacter = string[i]; +// const previousCharacter = string[i - 1]; + +// if(currentCharacter !== previousCharacter || currentRunLength == 9) { +// encodedStringCharacters.push(currentRunLength.toString()); +// encodedStringCharacters.push(previousCharacter); +// currentRunLength = 0; +// } +// currentRunLength++; +// } +// //! Handle the last run. +// encodedStringCharacters.push(currentRunLength.toString()); +// encodedStringCharacters.push(string[string.length - 1]); + +// return encodedStringCharacters.join(''); + +// } + +// //! myLogic : only working for few test cases. +// function runLengthEncoding(string) { +// let char = string[0]; +// let count = 1; +// let output = []; +// for(let i = 1; i <= string.length; i++) { +// if(char !== string[i]) { +// output.push(count + char); +// char = string[i]; +// count = 0; +// } +// if(char === string[i]) { +// count++; +// } +// if(count == 9) { +// let temp = count + char; +// output.push(temp); +// temp = ''; +// count = 0; +// } +// } +// return output.join(''); +// } + + +function runLengthEncoding(string) { + let resultStr = ""; + let counts = []; + let chars = []; + + for(let i = 0; i < string.length; i++) { + let j = i; + let char = string[i]; + let temp = 1; + while(char == string[j]) { + j++; + temp++; + } + counts.push(temp); + chars.push(string[i]); + i = j; + } + + + console.log(chars, counts) + for(let i = 0; i < counts.length; i++) { + if(counts[i] > 9) { + let k = counts[i] % 10; + let z = 9 + chars[i] + k + chars[i]; + resultStr += z; + } + else { + let a = counts[i] + chars[i]; + resultStr += a; + } + } + return resultStr; +} + +// Do not edit the line below. +exports.runLengthEncoding = runLengthEncoding; + + +// let str = 'AAAAAAAAAAAAABBCCCCDD'; +let str = 'aaAA'; + +console.log(runLengthEncoding(str)); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/smallestSubstringContaining.js b/Javascript-DSA/Strings/AlgoExpert/smallestSubstringContaining.js new file mode 100644 index 00000000..add44182 --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/smallestSubstringContaining.js @@ -0,0 +1,73 @@ +//! https://www.algoexpert.io/questions/Smallest%20Substring%20Containing +//! https://leetcode.com/problems/minimum-window-substring/ + +function smallestSubstringContaining(bigString, smallString) { + const targetCharCounts = getCharCounts(smallString); + const substringBounds = getStringBounds(bigString, targetCharCounts); + return getStringFromBounds(bigString, substringBounds); +} + +function getCharCounts(string) { + const charCounts = {}; + for(const char of string) { + increaseCharCount(char, charCounts); + } + return charCounts; +} + +function getStringBounds(string, targetCharCounts) { + let subStringBounds = [0, Infinity]; + const subStringCharCounts = {}; + const numUniqueChars = Object.keys(targetCharCounts).length; + let numUniqueCharsDone = 0; + let leftIdx = 0; + let rightIdx =0; + + while(rightIdx < string.length) { + const rightChar = string[rightIdx]; + if(!(rightChar in targetCharCounts)) { + rightIdx++; + continue; + } + increaseCharCount(rightChar, subStringCharCounts); + if(subStringCharCounts[rightChar] == targetCharCounts[rightChar]) { + numUniqueCharsDone++; + } + while(numUniqueCharsDone === numUniqueChars && leftIdx <= rightIdx) { + subStringBounds = getCloserBounds(leftIdx, rightIdx, subStringBounds[0], subStringBounds[1]); + const leftChar = string[leftIdx]; + if(!(leftChar in targetCharCounts)) { + leftIdx++; + continue; + } + if(subStringCharCounts[leftChar] === targetCharCounts[leftChar]) { + numUniqueCharsDone--; + } + decreaseCharCount(leftChar, subStringCharCounts); + leftIdx++; + } + rightIdx++; + } + return subStringBounds; +} + +function getCloserBounds(idx1, idx2, idx3, idx4) { + return idx2 - idx1 < idx4 - idx3 ? [idx1, idx2] : [idx3, idx4]; +} + +function increaseCharCount(char, charCounts) { + charCounts[char] = (charCounts[char] || 0) + 1; +} + +function decreaseCharCount(char, charCounts) { + charCounts[char]--; +} + +function getStringFromBounds(string, bounds) { + const [start, end] = bounds; + if(end == Infinity) return ''; + return string.slice(start, end + 1); + } + + + console.log(smallestSubstringContaining("abcd$ef$axb$c$", "$$abf")); \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/tempCodeRunnerFile.js b/Javascript-DSA/Strings/AlgoExpert/tempCodeRunnerFile.js new file mode 100644 index 00000000..4e15beea --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/tempCodeRunnerFile.js @@ -0,0 +1 @@ +smallestSubstringContaining \ No newline at end of file diff --git a/Javascript-DSA/Strings/AlgoExpert/validIPAddresses.js b/Javascript-DSA/Strings/AlgoExpert/validIPAddresses.js new file mode 100644 index 00000000..45fcdbfe --- /dev/null +++ b/Javascript-DSA/Strings/AlgoExpert/validIPAddresses.js @@ -0,0 +1,37 @@ +function validIPAddresses(string) { + const ipAddressesFound = []; + + for(let i = 0; i < Math.min(string.length, 4); i++) { + const currentIPAddressParts = ['', '', '', '']; + + currentIPAddressParts[0] = string.slice(0, i); + + if(!isValidPart(currentIPAddressParts[0])) continue; + + for(let j = i + 1; j < i + Math.min(string.length - i, 4); j++) { + currentIPAddressParts[1] = string.slice(i, j); + if(!isValidPart(currentIPAddressParts[1])) continue; + + for(let k = j + 1; k < j + Math.min(string.length - j, 4); k++) { + + currentIPAddressParts[2] = string.slice(j, k); + currentIPAddressParts[3] = string.slice(k); + if(!(isValidPart(currentIPAddressParts[2]) && isValidPart(currentIPAddressParts[3]))) continue; + + ipAddressesFound.push(currentIPAddressParts.join('.')); + } + } +} + return ipAddressesFound; +} + +function isValidPart(string) { + const stringAsInt = parseInt(string); + if(stringAsInt > 255) return false; + + return string.length == stringAsInt.toString().length; +} + +const string = '1921680'; + +console.log(validIPAddresses(string)); \ No newline at end of file diff --git a/Javascript-DSA/Striver/.DS_Store b/Javascript-DSA/Striver/.DS_Store new file mode 100644 index 00000000..eee6ee45 Binary files /dev/null and b/Javascript-DSA/Striver/.DS_Store differ diff --git a/Javascript-DSA/Striver/RecursionSeries/palindrome.js b/Javascript-DSA/Striver/RecursionSeries/palindrome.js new file mode 100644 index 00000000..27438c41 --- /dev/null +++ b/Javascript-DSA/Striver/RecursionSeries/palindrome.js @@ -0,0 +1,10 @@ +function palindrome(i, n, str) { + if(i >= n / 2) return true; + + if(str[i] !== str[n - i - 1]) return false; + + return palindrome(i + 1, n, str); +} + +const str = 'maadam'; +console.log(palindrome(0, str.length, str)); \ No newline at end of file diff --git a/Javascript-DSA/Striver/RecursionSeries/ratInMate.js b/Javascript-DSA/Striver/RecursionSeries/ratInMate.js new file mode 100644 index 00000000..63c5ee10 --- /dev/null +++ b/Javascript-DSA/Striver/RecursionSeries/ratInMate.js @@ -0,0 +1,48 @@ +function findPathHelper(i, j, arr, n, ans, mov, visited) { +if(i == n - 1 && j == n - 1) { + ans.push(mov); + return; +} + +// downward + if(i + 1 < n && !visited[i + 1][j] && arr[i + 1][j] === 1) { + visited[i][j] = 1; + findPathHelper(i + 1, j, arr, n, ans, mov + "D", visited); + visited[i][j] = 0; + } + // left + if(j - 1 > -1 && !visited[i][j - 1] && arr[i][j - 1] === 1) { + visited[i][j] = 1; + findPathHelper(i, j - 1, arr, n, ans, mov + "L", visited); + visited[i][j] = 0; + } + // right + if(j + 1 < n && !visited[i][j + 1] && arr[i][j + 1] === 1) { + visited[i][j] = 1; + findPathHelper(i, j + 1, arr, n, ans, mov + "R", visited); + visited[i][j] = 0; + } + // upward + if(i - 1 > -1 && !visited[i - 1][j] && arr[i - 1][j] === 1) { + visited[i][j] = 1; + findPathHelper(i - 1, j, arr, n, ans, mov + "U", visited); + visited[i][j] = 0; + } +} + +function findPath(m, n) { + var ans = []; + var visited = [...Array(n)].map(e => Array(n)); + if (m[0][0] === 1) findPathHelper(0, 0, m, n, ans, "", visited); + return ans; +} + +const m = [ [1, 0, 0, 0], + [1, 1, 0, 1], + [1, 1, 0, 0], + [0, 1, 1, 1] +]; +const n = 4; +console.log(findPath(m, n)); + + diff --git a/Javascript-DSA/Striver/RecursionSeries/subsequence.js b/Javascript-DSA/Striver/RecursionSeries/subsequence.js new file mode 100644 index 00000000..96dac55c --- /dev/null +++ b/Javascript-DSA/Striver/RecursionSeries/subsequence.js @@ -0,0 +1,47 @@ +// O(2**N * N) time | O(N) space + +function subsequence(i, n, array, sequence) { + if (i === n) { + if (sequence.length == 0) { + console.log("{}"); + } else console.log(sequence); + return; + } + + //take or pick the particular index into the subsequence. + sequence.push(array[i]); + subsequence(i + 1, n, array, sequence); + sequence.pop(); + + //Do not take or do not pick the particular index into the subsequence. + subsequence(i + 1, n, array, sequence); +} + +const array = [3, 1, 2]; + +// subsequence(0, array.length, array, []); + + +//! Reverse order + +function subsequenceReverse(i, n, array, sequence) { + if (i === n) { + if (sequence.length == 0) { + console.log("{}"); + } else console.log(sequence); + return; + } + + //Do not take or do not pick the particular index into the subsequence. + subsequenceReverse(i + 1, n, array, sequence); + + //take or pick the particular index into the subsequence. + sequence.push(array[i]); + subsequenceReverse(i + 1, n, array, sequence); + sequence.pop(); +} + + + + +subsequenceReverse(0, array.length, array, []); \ No newline at end of file diff --git a/Javascript-DSA/Striver/RecursionSeries/subsequenceSum.js b/Javascript-DSA/Striver/RecursionSeries/subsequenceSum.js new file mode 100644 index 00000000..983ec8fd --- /dev/null +++ b/Javascript-DSA/Striver/RecursionSeries/subsequenceSum.js @@ -0,0 +1,22 @@ +function subsequenceSum(i, nums, currentSum, array, sum) { + + if(i == n) { + if(currentSum == sum) { + console.log(nums); + } + return; + } + nums.push(array[i]); + currentSum += array[i]; + subsequenceSum(i + 1, nums, currentSum, array, sum); + + currentSum -= array[i]; + nums.pop(); + subsequenceSum(i + 1, nums, currentSum, array, sum); +} + +const array = [1, 2, 1]; +const n = array.length; +const sum = 2; + +subsequenceSum(0, [], 0, array, sum); diff --git a/Javascript-DSA/Striver/RecursionSeries/swapNumbers.js b/Javascript-DSA/Striver/RecursionSeries/swapNumbers.js new file mode 100644 index 00000000..c7deacaf --- /dev/null +++ b/Javascript-DSA/Striver/RecursionSeries/swapNumbers.js @@ -0,0 +1,13 @@ +function swapNumbers(i, n, array) { + if(i >= n / 2) return; + swap(i, n - i - 1, array); + swapNumbers(i + 1, n, array); +} + +function swap(a, b, array) { + [ array[a], array[b]] = [ array[b], array[a]]; +} + +const array = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; +swapNumbers(0, array.length, array); +console.log(array); \ No newline at end of file diff --git a/Javascript-DSA/Tries/trie_implimentation.js b/Javascript-DSA/Tries/trie_implimentation.js new file mode 100644 index 00000000..f2d4f6d2 --- /dev/null +++ b/Javascript-DSA/Tries/trie_implimentation.js @@ -0,0 +1,72 @@ +class TrieNode { + constructor(value) { + this.data = value; + this.isEndOfWord = false; + this.children = new Map(); + } +} + +function insert(root, str) { + let temp = root; + for(let i = 0; i < str.length; i++) { + let data = str[i]; + if(temp.children.get(data)){ + temp = temp.children.get(data); + } else { + temp.children.set(data, new TrieNode(data)); + temp = temp.children.get(data); + } + } + temp.isEndOfWord = true; +} + +function search(root, str) { + let temp = root; + for(let i = 0; i < str.length; i++) { + let data = str[i]; + if(temp.children.get(data)){ + temp = temp.children.get(data); + } else { + return false; + } + } + return temp.isEndOfWord == true; +} + +function helper(root, pre, output) { + if(!root) return; + if(root.isEndOfWord) { + console.log(pre + output); + } + for(const [key, value] of root.children.entries()) { + helper(value, pre, output + key); + } + } + +function prefix_search(root, pre) { + let temp = root; + for(let i = 0; i < pre.length; i++) { + let data = pre[i]; + if(temp.children.get(data)) { + temp = temp.children.get(data); + } else { + console.log("Prefix not found"); + return; + } + } + helper(temp, pre, ""); +} + +let rootNode = new TrieNode('\0'); + +insert(rootNode, "bat"); +insert(rootNode, "batman"); +insert(rootNode, "super"); +insert(rootNode, "superman"); +insert(rootNode, "batgirl"); +insert(rootNode, "wonder"); +insert(rootNode, "woman"); + +// console.log(search(rootNode, "batgirl")); + +prefix_search(rootNode, "bat"); \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/.DS_Store b/Javascript-DSA/linkedLists/.DS_Store new file mode 100644 index 00000000..d7526038 Binary files /dev/null and b/Javascript-DSA/linkedLists/.DS_Store differ diff --git a/Javascript-DSA/linkedLists/AlgoExpert/LRU-Cache.js b/Javascript-DSA/linkedLists/AlgoExpert/LRU-Cache.js new file mode 100644 index 00000000..d694f5c2 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/LRU-Cache.js @@ -0,0 +1,102 @@ +class LRUCache { + constructor(maxSize) { + this.cache = {}; + this.maxSize = maxSize || 1; + this.currentSize = 0; + this.listOfMostRecent = new DoubleLinkedList(); + } + + //! O(1) time | O(1) space | space depends on maxSize. + insertKeyValuePair(key, value) { + if(!(key in this.cache)) { + if(this.currentSize == this.maxSize) { + this.evictLeastRecent(); + } else { + this.currentSize++; + } + this.cache[key] = new DoubleLinkedListNode(key, value); + } else { + this.replaceKey(key, value); + } + this.updateMostRecent(this.cache[key]); +} + //! O(1) time | O(1) space + getValueFromKey(key) { + if (!(key in this.cache)) return null; + this.updateMostRecent(this.cache[key]); + return this.cache[key].value; + } + + //! O(1) time | O(1) space + getMostRecentKey() { + if(!this.listOfMostRecent.head) return; + return this.listOfMostRecent.head.key; + } + evictLeastRecent() { + const keyToRemove = this.listOfMostRecent.tail.key; + this.listOfMostRecent.removeTail(); + delete this.cache[keyToRemove]; + } + updateMostRecent(node) { + this.listOfMostRecent.setHeadTo(node); + } + + replaceKey(key, value) { + if(!(key in this.cache)) { + throw new Error("This provided key isn't in the cache!"); + } + this.cache[key].value = value; + } +} +class DoubleLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + setHeadTo(node) { + if(this.head == node) { + return; + } else if(this.head == null) { + this.head = node; + this.tail = node; + } else if(this.head == this.tail) { + this.tail.prev = node; + this.head = node; + this.head.next = this.tail; + } else { + if(this.tail == node) this.removeTail(); + node.removeBindings(); + this.head.prev = node; + node.next = this.head; + this.head = node; + } + } + removeTail() { + if(this.tail == null) return; + if(this.tail == this.head) { + this.head = null; + this.tail = null; + return; + } + this.tail = this.tail.prev; + this.tail.next = null; + } + } +class DoubleLinkedListNode { + constructor(key, value) { + this.key = key; + this.value = value; + this.prev = null; + this.next = null; + } + removeBindings() { + if(this.prev != null) { + this.prev.next = this.next; + } + if(this.next != null) { + this.next.prev = this.prev; + } + this.prev = null; + this.next = null; + } +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/doublyLinkedListConstruction.js b/Javascript-DSA/linkedLists/AlgoExpert/doublyLinkedListConstruction.js new file mode 100644 index 00000000..e656564a --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/doublyLinkedListConstruction.js @@ -0,0 +1,110 @@ +class Node { + constructor(value) { + this.value = value; + this.prev = null; + this.next = null; + } +} + +class DoubleLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + //! O(1) time | O(1) space + setHead(node) { + if(this.head == null) { + this.head = node; + this.tail = node; + } else { + this.insertBefore(this.head, node); + } + } + //! O(1) time | O(1) space + setTail(node) { + if(this.tail == null) { + this.setHead(node); + } else { + this.insertAfter(this.tail, node); + } + } + //! O(1) time | O(1) space + insertBefore(node, nodeToInsert) { + if(nodeToInsert == this.head && nodeToInsert == this.tail) { + return; + } + this.remove(nodeToInsert); + nodeToInsert.prev = node.prev; + nodeToInsert.next = node; + if(node.prev == null) { + this.head = nodeToInsert; + } + else { + node.prev.next = nodeToInsert; + } + node.prev = nodeToInsert; + } + //! O(1) time | O(1) space + insertAfter(node, nodeToInsert) { + if(nodeToInsert == this.head && nodeToInsert == this.tail) { + return; + } + this.remove(nodeToInsert); + nodeToInsert.prev = node; + nodeToInsert.next = node.next; + if(node.next == null) { + this.tail = nodeToInsert; + } + else { + node.next.prev = nodeToInsert; + } + node.next = nodeToInsert; + } + //! O(p) time | O(1) space where p is position + insertAtPosition(position, nodeToInsert) { + if(position == 1) { + this.setHead(nodeToInsert); + return; + } + let node = this.head; + let currentPosition = 1; + while(node != null && currentPosition++ != position) node = node.next; + if(node != null) { + this.insertBefore(node, nodeToInsert); + } else { + this.setTail(nodeToInsert); + } + } + //! O(n) time | O(1) space + removeNodeWithValue(value) { + let node = this.head; + while(node != null) { + const nodeToRemove = node; //! we traversing till the end of list because there may be many nodes with same value. + node = node.next; + if(nodeToRemove.value == value) { + this.remove(nodeToRemove); + } + } + } + //! O(1) time | O(1) space + remove(node) { + if(node == this.head) this.head = this.head.next; + if(node == this.tail) this.tail = this.tail.prev; + this.removeNodeBindings(node); + } + //! O(n) time | O(1) space + containsNodeWithValue(value) { + let node = this.head; + while(node != null && node.value != value) { + node = node.next; + } + return node != null; + } + //! O(1) time | O(1) space + removeNodeBindings(node) { + if(node.prev != null) node.prev.next = node.next; + if(node.next != null) node.next.prev = node.prev; + node.prev = null; + node.next = null; + } +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/dummy1.js b/Javascript-DSA/linkedLists/AlgoExpert/dummy1.js new file mode 100644 index 00000000..f4b358c8 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/dummy1.js @@ -0,0 +1,105 @@ +class LRUCache { + constructor(maxSize) { + this.cache = {}; + this.maxSize = maxSize || 1; + this.currentSize = 0; + this.listOfMostRecent = new DoublyLinkedList(); + } + + insertKeyValuePair(key, value) { + if( !(key in this.cache)) { + if(this.currentSize == this.maxSize) { + this.evictLeastRecent(); + } else { + this.currentSize++; + } + this.cache[key] = new DoublyLinkedListNode(key, value); + } else { + this.replaceKey(key, value); + } + this.updateMostRecent(this.cache[key]); + } + getValueFromKey(key) { + if(!(key in this.cache)) { + return null; + } + this.updateMostRecent(this.cache[key]); + return this.cache[key].value; + } + getMostRecentKey() { + if(!this.listOfMostRecent.head) return; + return this.listOfMostRecent.head.key; + } + evictLeastRecent() { + const keyToRemove = this.listOfMostRecent.tail.key; + this.listOfMostRecent.removeTail(); + delete this.cache[keyToRemove]; + } + updateMostRecent(node) { + this.listOfMostRecent.setHeadTo(node); + } + replaceKey(key, value) { + if(!(key in this.cache)) { + throw new Error("The provided key isn't in the cache!"); + } + this.cache[key].value = value; + } +} + +class DoublyLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + + setHeadTo(node) { + if(this.head == node) { + return; + } else if(this.head == null) { + this.head = node; + this.tail = node; + } else if(this.head == this.tail) { + this.tail.prev = node; + this.head = node; + this.head.next = this.tail; + } else { + if(this.tail == node) this.removeTail(); + node.removeBindings(); + this.head.prev = node; + node.next = this.head; + this.head = node; + } + } + removeTail() { + if(this.tail == null) return; + if(this.tail == this.head) { + this.head = null; + this.tail = null; + return; + } + this.tail = this.tail.prev; + this.tail.next = null; + } + } + + class DoublyLinkedListNode { + constructor(key, value) { + this.key = key; + this.value = value; + this.prev = null; + this.next = null; + } + + removeBindings() { + if(this.prev != null) { + this.prev.next = this.next; + } + if(this.next != null) { + this.next.prev = this.prev; + } + this.next = null; + this.prev = null; + } + } +// Do not edit the line below. +exports.LRUCache = LRUCache; diff --git a/Javascript-DSA/linkedLists/AlgoExpert/dummy2.js b/Javascript-DSA/linkedLists/AlgoExpert/dummy2.js new file mode 100644 index 00000000..49912f13 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/dummy2.js @@ -0,0 +1,109 @@ +// Do not edit the class below except for the insertKeyValuePair, +// getValueFromKey, and getMostRecentKey methods. Feel free +// to add new properties and methods to the class. +class LRUCache { + constructor(maxSize) { + this.cache = {}; + this.maxSize = maxSize || 1; + this.currentSize = 0; + this.listOfMostRecent = new DoublyLinkedList(); + } + + insertKeyValuePair(key, value) { + if(!(key in this.cache)) { + if(this.currentSize === this.maxSize) { + this.evictLeastRecent(); + } else { + this.currentSize++; + } + this.cache[key] = new DoublyLinkedListNode(key, value); + } else { + this.replaceKey(key, value); + } + this.updateMostRecent(this.cache[key]); + } + + getValueFromKey(key) { + if(!(key in this.cache)) return null; + this.updateMostRecent(this.cache[key]); + return this.cache[key].value; + } + + getMostRecentKey() { + if(!this.listOfMostRecent.head) return; + return this.listOfMostRecent.head.key; + } + evictLeastRecent() { + const keyToRemove = this.listOfMostRecent.tail.key; + this.listOfMostRecent.removeTail(); + delete this.cache[keyToRemove]; + } + + updateMostRecent(node) { + this.listOfMostRecent.setHeadTo(node); + } + + replaceKey(key, value) { + if(!(key in this.cache)) { + throw new Error("This provided key isn't in the cache!") + } + this.cache[key].value = value; + } +} +class DoublyLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + + setHeadTo(node) { + if(this.head === node) { + return; + } else if(this.head === null) { + this.head = node; + this.tail = node; + } else if(this.head === this.tail) { + this.tail.prev = node; + this.head = node; + this.head.next = this.tail; + } else { + if(this.tail === node) this.removeTail(); + node.removeBindings(); + this.head.prev = node; + node.next = this.head; + this.head = node; + } + } + removeTail() { + if(this.tail === null) return; + if(this.tail === this.head) { + this.head = null; + this.tail = null; + return; + } + this.tail = this.tail.prev; + this.tail.next = null; + } +} + +class DoublyLinkedListNode { + construct(key, value) { + this.key = key; + this.value = value; + this.prev = null; + this.next = null; + } + + removeBindings() { + if(this.prev != null) { + this.prev.next = this.next; + } + if(this.next != null) { + this.next.prev = this.prev; + } + this.prev = null; + this.next = null; + } +} +// Do not edit the line below. +exports.LRUCache = LRUCache; diff --git a/Javascript-DSA/linkedLists/AlgoExpert/findLoop.js b/Javascript-DSA/linkedLists/AlgoExpert/findLoop.js new file mode 100644 index 00000000..fdf79030 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/findLoop.js @@ -0,0 +1,22 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n) time | O(1) space +function findLoop(head) { + let first = head.next; + let second = head.next.next; + + while(first != second) { + first = first.next; + second = second.next.next; + } + first = head; + while(first != second) { + first = first.next; + second = second.next + } + return first; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/linkedListPalindrome.js b/Javascript-DSA/linkedLists/AlgoExpert/linkedListPalindrome.js new file mode 100644 index 00000000..a2415bb3 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/linkedListPalindrome.js @@ -0,0 +1,68 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(1) space + +function linkedListPalindrome(head) { + + let fastNode = head; + let slowNode = head; + + while(fastNode != null && fastNode.next != null) { + slowNode = slow.next; + fastNode = fastNode.next.next; + } + + let reversedSecondHalfNode = reverseLinkedList(slowNode); + let firstHalfNode = head; + + while(reversedSecondHalfNode != null) { + if(reversedSecondHalfNode.value != firstHalfNode.value) { + return false; + } + reversedSecondHalfNode = reversedSecondHalfNode.next; + firstHalfNode = firstHalfNode.next; + } + return true; +} + +function reverseLinkedList(head) { + let previousNode = null; + let currentNode = head; + + while(currentNode != null) { + let nextNode = currentNode.next; + currentNode.next = previousNode; + previousNode = currentNode; + currentNode = nextNode; + } + return previousNode; +} + +//! O(n) time | O(n) space +function linkedListPalindrome(head) { + let currentNode = head; + let values = []; + let len = 0; + + while(currentNode != null) { + values[len++] = currentNode.value; + currentNode = currentNode.next; + } + + let i = 0; + let j = values.length - 1; + + while( i < j) { + if(values[i] != values[j]) { + return false; + } + i++; + j--; + } +return true; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/mergeLinkedLists.js b/Javascript-DSA/linkedLists/AlgoExpert/mergeLinkedLists.js new file mode 100644 index 00000000..faff6740 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/mergeLinkedLists.js @@ -0,0 +1,53 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n + m) time | O(1) space +function mergeLinkedLists(headOne, headTwo) { + let p1 = headOne; + let p1Prev = null; + let p2 = headTwo; + + while(p1 && p2) { + if(p1.value < p2.value) { + p1Prev = p1; + p1 = p1.next; + } else { + if(!p1Prev) { + p1Prev.next = p2; + p1Prev = p2; + p2 = p2.next; + p1Prev.next = p1; + } + } + } + if(p1 == null) { + p1Prev.next = p2; + } + return headOne.value < headTwo.value ? headOne: headTwo; +} + +//! O(n + m) time | O(n + m) space +function mergeLinkedLists(headOne, headTwo) { + recursiveMerge(headOne, headTwo, null); + return headOne.value < headTwo.value ? headOne: headTwo; +} + +function recursiveMerge(p1, p2, p1Prev) { + if(p1 == null) { + p1Prev.next = p2; + return; + } + if(p2 == null) return; + + if(p1.value < p2.value) { + recursiveMerge(p1.next, p2, p1); + } else { + if(p1Prev != null) p1Prev.next = p2; + const newP2 = p2.next; + p2.next = p1; + recursiveMerge(p1, newP2, p2); + } +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/nodeSwap.js b/Javascript-DSA/linkedLists/AlgoExpert/nodeSwap.js new file mode 100644 index 00000000..96bc5d9a --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/nodeSwap.js @@ -0,0 +1,39 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(n) space +function nodeSwap(head) { + if(head == null || head.next == null) return head; + + const nodeNext = head.next; + + head.next = nodeSwap(head.next.next); + + nodeNext.next = head; + + return nextNode; +} + +//! O(n) time | O(1) space +function nodeSwap(head) { + let tempNode = new LinkedList(0); + tempNode.next = head; + let previousNode = tempNode.prev; + + while(previousNode.next != null && previousNode.next.next != null) { + const firstNode = previousNode.next; + const secondNode = previousNode.next.next; + + firstNode.next = secondNode.next; + secondNode.next = firstNode; + previousNode.next = secondNode; + + previousNode = firstNode; + } + + return tempNode.next; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/oddEvenLinkedList.js b/Javascript-DSA/linkedLists/AlgoExpert/oddEvenLinkedList.js new file mode 100644 index 00000000..ee5b1e2b --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/oddEvenLinkedList.js @@ -0,0 +1,23 @@ +//! https://leetcode.com/problems/odd-even-linked-list/ + + + +//! O(n) time | O(1) space + +function oddEvenList(head) { + + if(!head) return null; + + let odd = head; + let even = head.next; + let evenHead = even; + + while(even && even.next) { + odd.next = even.next; + odd = odd.next; + even.next = odd.next; + even = even.next; + } + odd.next = evenHead; + return head; +}; \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/rearrangeLinkedList.js b/Javascript-DSA/linkedLists/AlgoExpert/rearrangeLinkedList.js new file mode 100644 index 00000000..0256e640 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/rearrangeLinkedList.js @@ -0,0 +1,59 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(1) space +function rearrangeLinkedList(head, k) { + let smallerListHead = null; + let smallerListTail = null; + let equalListHead = null; + let equalListTail = null; + let greaterListHead = null; + let greaterListTail = null; + + let node = head; + + while(node != null) { + if(node.value < k) { + [smallerListHead, smallerListTail] = growLinkedList(smallerListHead, smallerListTail, node); + } else if(node.value > k) { + [greaterListHead, greaterListTail] = growLinkedList(greaterListHead, greaterListTail, node); + } else { + [equalListHead, equalListTail] = growLinkedList(equalListHead, equalListTail, node); + } + const prevNode = node; + node = node.next; + prevNode.next = null; + } + const [firstHead, firstTail] = connectLinkedLists(smallerListHead, smallerListTail, equalListHead, equalListTail); + const [finalHead, _] = connectLinkedLists(firstHead, firstTail, greaterListHead, greaterListTail); + return finalHead; +} + +function growLinkedList(head, tail, node) { + let newHead = head; + let newTail = node; + + if(newHead == null) { + newHead = node; + } + if(tail != null) { + tail.next = node; + } + return [newHead, newTail]; +} + +function connectLinkedLists(headOne, tailOne, headTwo, tailTwo) { + + const newHead = headOne == null ? headTwo: headOne; + const newTail = tailTwo == null ? tailOne: tailTwo; + + if(tailOne != null) { + tailOne.next = headTwo; + } + return [newHead, newTail]; + +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/removeDuplicatesFromLinkedList.js b/Javascript-DSA/linkedLists/AlgoExpert/removeDuplicatesFromLinkedList.js new file mode 100644 index 00000000..5b30af13 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/removeDuplicatesFromLinkedList.js @@ -0,0 +1,21 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n) time | O(1) space +function removeDuplicatesFromLinkedList(linkedList) { + let currentNode = linkedList; + while(currentNode != null) { + let nextDistinctNode = currentNode.next; + while(nextDistinctNode != null && currentNode.value == nextDistinctNode.value) { + const temp = nextDistinctNode; + nextDistinctNode = nextDistinct.next; + temp.next = null; + } + currentNode.next = nextDistinctNode; + currentNode = currentNode.next; + } + return linkedList; +} diff --git a/Javascript-DSA/linkedLists/AlgoExpert/removeKthNodeFromEnd.js b/Javascript-DSA/linkedLists/AlgoExpert/removeKthNodeFromEnd.js new file mode 100644 index 00000000..b01188a7 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/removeKthNodeFromEnd.js @@ -0,0 +1,37 @@ +class Node { + constructor(value) { + this.value = value; + this.next = null; + } +} +class LinkedList { + constructor() { + this.head = null; + } + insertElementAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + this.head = newNode; + } +} + +function removeKthNodeFromEnd(head, k) { + let first = head; + let second = head; + let counter = 1; + while(counter <= k) { + second = second.next; + } + if(second == null) { + let temp = head; + head = head.next; + temp.next = null; + return; + } + while(second.next != null) { + first = first.next; + second = second.next; + } + first.next = first.next.next; +} + diff --git a/Javascript-DSA/linkedLists/AlgoExpert/reverseLinkedList.js b/Javascript-DSA/linkedLists/AlgoExpert/reverseLinkedList.js new file mode 100644 index 00000000..6b8607c5 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/reverseLinkedList.js @@ -0,0 +1,19 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n) time | O(1) space +function reverseLinkedList(head) { + + let previousNode = null; + let currentNode = head; + while(currentNode) { + const nextNode = currentNode.next; + currentNode.next = previousNode; + previousNode = currentNode; + currentNode = nextNode; + } + return previousNode; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/reverseSingleLinkedList.js b/Javascript-DSA/linkedLists/AlgoExpert/reverseSingleLinkedList.js new file mode 100644 index 00000000..84392c5c --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/reverseSingleLinkedList.js @@ -0,0 +1,68 @@ +class Node { //! Node class + constructor(data) { + this.data = data; + this.next = null; + } +} + +class SingleLinkedList { //! linkedlist class + constructor() { + this.head = null; + this.length = 0; + } + //! insert at start + insertElementAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + this.head = newNode; + this.length++; + } + //! insert at end + insertElementAtEnd(data) { + let newNode = new Node(data); //! create a new node + let s = null; //! to keep track of current head + if(this.head == null) { + this.head = newNode; + } + else { + s = this.head; + while(s.next != null) { + s = s.next; + } + s.next = newNode; + } + this.length++; + } + printSingleLinkedList() { + let current = this.head; + while(current) { + console.log(current); + current = current.next; + } + } + + reverseLinkedList() { + let prev = null; + let current = this.head; + while (current) { + let following = current.next; + current.next = prev; + prev = current; + current = following; + } + let s = prev; + while(s) { + console.log(s); + s = s.next; + } + } + +} +let singleLinkedList = new SingleLinkedList(); +singleLinkedList.insertElementAtStart(10); +singleLinkedList.insertElementAtEnd(20); +singleLinkedList.insertElementAtEnd(30); +singleLinkedList.insertElementAtEnd(40); +singleLinkedList.reverseLinkedList(); + + diff --git a/Javascript-DSA/linkedLists/AlgoExpert/shiftLinkedList.js b/Javascript-DSA/linkedLists/AlgoExpert/shiftLinkedList.js new file mode 100644 index 00000000..e6ef9d5a --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/shiftLinkedList.js @@ -0,0 +1,31 @@ +//! O(n) time | O(1) space + +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +function shiftLinkedList(head, k) { + let listLength = 1; + let listTail = head; + while(listTail.next != null) { + listTail = listTail.next; + listLength++; + } + const offset = Math.abs(k) % listLength; + if(offset == 0) return head; + + const newTailPosition = k > 0 ? listLength - offset : offset; + let newTail = head; + for(let i = 1; i < newTailPosition; i++) { + newTail = newTail.next; + } + + const newHead = newTail.next; + newTail.next = null; + listTail.next = head; + return newHead; + +} diff --git a/Javascript-DSA/linkedLists/AlgoExpert/sumOfLinkedLists.js b/Javascript-DSA/linkedLists/AlgoExpert/sumOfLinkedLists.js new file mode 100644 index 00000000..2be1b13f --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/sumOfLinkedLists.js @@ -0,0 +1,32 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(max(m, n)) time | O(max(m, n)) space +function sumOfLinkedLists(linkedListOne, linkedListTwo) { + const newLinkedListHeadPointer = new LinkedList(0); + let currentNode = newLinkedListHeadPointer; + let carry = 0; + + let nodeOne = linkedListOne; + let nodeTwo = linkedListTwo; + + while(nodeOne != null || nodeTwo != null || carry != 0) { + const valueOne = nodeOne != null ? nodeOne.value: 0; + const valueTwo = nodeTwo != null ? nodeTwo.value: 0; + const sumOfValues = valueOne + valueTwo + carry; + + const newValue = sumOfValues % 10; + const newNode = new LinkedList(newValue); + currentNode.next = newNode; + currentNode = newNode; + + carry = Math.floor(sumOfValues / 10); + nodeOne = nodeOne.next != null ? nodeOne.next: null; + nodeTwo = nodeTwo.next != null ? nodeTwo.next: null; + } + return newLinkedListHeadPointer.next; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/AlgoExpert/zipLinkedList.js b/Javascript-DSA/linkedLists/AlgoExpert/zipLinkedList.js new file mode 100644 index 00000000..78140ad4 --- /dev/null +++ b/Javascript-DSA/linkedLists/AlgoExpert/zipLinkedList.js @@ -0,0 +1,64 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(1) space +function zipLinkedList(linkedList) { + if(linkedList.next != null || linkedList.next.next != null) return linkedList; + + const firstHalfHead = linkedList; + const secondHalfHead = splitLinkedList(linkedList); + + const reversedSecondHalfHead = reverseLinkedList(secondHalfHead); + + return combineLinkedLists(firstHalfHead, reversedSecondHalfHead); + +} + +function splitLinkedList(linkedList) { + let slowIterator = linkedList; + let fastIterator = linkedList; + + while(fastIterator != null && fastIterator.next != null) { + slowIterator = slowIterator.next; + fastIterator = fastIterator.next.next; + } + + const secondHalfHead = slowIterator.next; + slowIterator.next = null; + + return secondHalfHead; +} + +function combineLinkedLists(linkedList1, linkedList2) { + let linkedList1Iterator = linkedList1; + let linkedList2Iterator = linkedList2; + + while(linkedList2Iterator) { + let linkedList1IteratorNext = linkedList1Iterator.next; + let linkedList2IteratorNext = linkedList2Iterator.next; + + linkedList1Iterator.next = linkedList2Iterator; + linkedList2Iterator.next = linkedList1IteratorNext; + + linkedList1Iterator = linkedList1IteratorNext; + linkedList2Iterator = linkedList2IteratorNext; + } + return linkedList1; +} + +function reverseLinkedList(head) { + let previousNode = null; + let currentNode = head; + + while(currentNode != null) { + const nextNode = currentNode.next; + currentNode.next = previousNode; + previousNode = currentNode; + currentNode = nextNode; + } + return previousNode; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/LinkedListMergeSort.js b/Javascript-DSA/linkedLists/LinkedListMergeSort.js new file mode 100644 index 00000000..ddbfa308 --- /dev/null +++ b/Javascript-DSA/linkedLists/LinkedListMergeSort.js @@ -0,0 +1,59 @@ +function mergeSort(head) { +if(head == null || head.next == null) return head; + + const mid = findMid(head); + let left = head; + let right = mid.next; + mid.next = null; + + left = mergeSort(left); + right = mergeSort(right); + + return mergeTwoLists(left, right); +} + +function findMid(head) { + let slow = head; + let fast = head.next; + + while(fast != null && fast.next == null) { + slow = slow.next; + fast = fast.next.next; + } +} + +function mergeTwoLists(left, right) { + + if(left == null) return right; + if(right == null) return left; + + let dummy = new Node(-1); + + let currentNode = dummy; + + while(left != null && right != null) { + if(left.value < right.value) { + currentNode.next = left; + currentNode = currentNode.next; + left = left.next; + } else { + currentNode.next = right; + currentNode = currentNode.next; + right = right.next; + } + } + + while(left != null) { + currentNode.next = left; + currentNode = currentNode.next; + left = left.next; + } + + while(right != null) { + currentNode.next = right; + currentNode = currentNode.next; + right = right.next; + } + + return dummy.next; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/StriverSheet/.DS_Store b/Javascript-DSA/linkedLists/StriverSheet/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/Javascript-DSA/linkedLists/StriverSheet/.DS_Store differ diff --git a/Javascript-DSA/linkedLists/StriverSheet/flattenLinkedList.js b/Javascript-DSA/linkedLists/StriverSheet/flattenLinkedList.js new file mode 100644 index 00000000..6039e00c --- /dev/null +++ b/Javascript-DSA/linkedLists/StriverSheet/flattenLinkedList.js @@ -0,0 +1,38 @@ +//! https://www.codingninjas.com/codestudio/problems/1112655 + +function flatten(root) { + if(root == null || root.next == null) return root; + + root.next = flatten(root.next); + + root = mergeLists(root, root.next); + + return root; +} + + +function mergeLists(list1, list2) { + if(list1 == null || list2 == null) return list1 || list2; + + let dummyNode = new Node(0); + let currentNode = dummyNode; + + while(list1 != null && list2 != null) { + if(list1.value < list2.value) { + currentNode.bottom = list1; + currentNode = currentNode.bottom; + list1 = list1.bottom; + } else { + currentNode.bottom = list2; + currentNode = currentNode.bottom; + list2 = list2.bottom; + } + } + + if(list1) currentNode.bottom = list1; + else currentNode.bottom = list2; + + return dummyNode.bottom; +} + + diff --git a/Javascript-DSA/linkedLists/StriverSheet/intersectionOfTwoNodes.js b/Javascript-DSA/linkedLists/StriverSheet/intersectionOfTwoNodes.js new file mode 100644 index 00000000..0e11183a --- /dev/null +++ b/Javascript-DSA/linkedLists/StriverSheet/intersectionOfTwoNodes.js @@ -0,0 +1,14 @@ +// https://leetcode.com/problems/intersection-of-two-linked-lists/ + +function getIntersectionNode (headA, headB) { + + let headANode = headA; + let headBNode = headB; + + while(headANode !== headBNode) { + headANode = headANode === null ? headB : headANode.next; + headBNode = headBNode === null ? headA : headBNode.next; + } + return headANode; +} + diff --git a/Javascript-DSA/linkedLists/StriverSheet/reverseInKGroups.js b/Javascript-DSA/linkedLists/StriverSheet/reverseInKGroups.js new file mode 100644 index 00000000..59a83a72 --- /dev/null +++ b/Javascript-DSA/linkedLists/StriverSheet/reverseInKGroups.js @@ -0,0 +1,33 @@ +//!https://leetcode.com/problems/reverse-nodes-in-k-group/ + +function reverseKGroups(head, k) { + + if(head == null || k == 0) return head; + + let tempNode = new LinkedList(0); + + let previousNode = tempNode; + let currentNode = tempNode; + let nextNode = tempNode; + + let len = 0; + while(currentNode.next != null) { + currentNode = currentNode.next; + len++; + } + + while(len >= k) { + currentNode = previousNode.next; + nextNode = currentNode.next; + + for(let i = 1; i < k; i++) { + currentNode.next = nextNode.next; + nextNode.nextNode = previousNode.next; + previousNode.next = nextNode; + nextNode = currentNode.next; + } + prevNode = currentNode; + len -= k; + } + return tempNode.next; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/StriverSheet/rotateList.js b/Javascript-DSA/linkedLists/StriverSheet/rotateList.js new file mode 100644 index 00000000..277b7dcc --- /dev/null +++ b/Javascript-DSA/linkedLists/StriverSheet/rotateList.js @@ -0,0 +1,31 @@ +//!62 https://leetcode.com/problems/rotate-list/ + +function rotateList(head, k) { + + if(head == null) return null; + + let tail = head; + let len = 1; + + while(tail.next != null) { + tail = tail.next; + len++; + } + + tail.next = head; + + k = k % len; + + let currentNode = head; + + let counter = 1; + + while(counter <= len - k - 1) { + currentNode = currentNode.next; + counter++; + } + + const newHead = currentNode.next; + currentNode.next = null; + return newHead; +} \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/circularLinkedList.js b/Javascript-DSA/linkedLists/circularLinkedList.js new file mode 100644 index 00000000..3c3e8cb1 --- /dev/null +++ b/Javascript-DSA/linkedLists/circularLinkedList.js @@ -0,0 +1,155 @@ +class Node { + constructor(data) { + this.data = data; + this.next = null; + } +} + +class CircularLinkedList { + constructor() { + this.tail = null; + this.length = 0; + } + + insertToEmpty(tail, data) { + if(this.tail != null) { + return this.tail; + } + let newNode = new Node(data); + this.tail = newNode; + this.tail.next = newNode; + this.length++; + + return this.tail; + } + printCircularLinkedList(tail) { + let current; + + if(tail == null) { + console.log("List is empty"); + return; + } + + current = this.tail.next; + do { + console.log(current.data); + current = current.next; + } while(current != this.tail.next); + } + + size() { + console.log(this.length); + } + + insertAtStart(data) { + if(this.tail == null) { + return this.insertToEmpty(this.tail, data); + } + let newNode = new Node(data); + + newNode.next = this.tail.next; //! set next node of new node to current head. + this.tail.next = newNode; + this.length++; + return this.tail; + } + + insertAtEnd(data) { + if (this.tail == null) { + return this.insertToEmpty(this.tail, data); + } + let newNode = new Node(data); + newNode.next = this.tail.next; + this.tail.next = newNode; + this.tail = newNode; + this.length++; + return this.tail; + } + insertAtIndex(data, index) { + if(index == 0) { + this.insertAtStart(data); + } else if (index < 0 || index >= this.length) { + console.log("Array index out of bounds"); + } else { + let newNode = new Node(data); + let current, previous; + current = this.tail.next; + let count = 0; + while (count < index) { + previous = current; + current = current.next; + count++; + } + newNode.next = current; + previous.next = newNode; + + this.length++; + return this.tail; + } + } + getElement() { + if (index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.tail.next; + let count = 0; + do { + if (count == index && current != null) { + console.log(current.data); + } + count++; + current = current.next; + } while (current != this.tail.next); + } + } + removeAt(index) { + if (index == 0) { + if(this.tail.next != null) { + return false; + } + let current = this.tail.next; + this.tail.next = current.next; + current = null; + + this.length--; + } else if (index < 0 || index >= this.length) { + console.log("Array index out of bounds"); + } else { + let current, previous; + current = this.tail.next; + let count = 0; + while (count < index) { + count++; + previous = current; + current = current.next; + } + previous.next = current.next; + current = null; + this.length--; + + } + } +} + +const cll = new CircularLinkedList(); +// cll.insertAtStart(500); +// cll.insertAtStart(1000); +// cll.insertAtEnd(800); +// cll.insertAtEnd(600); +// cll.insertAtIndex(50, 1); +// cll.insertAtIndex(250, 3); +// cll.printCircularLinkedList(); + +tail = cll.insertAtStart(500); +tail = cll.insertAtStart(1000); +tail = cll.insertAtEnd(800); +tail = cll.insertAtEnd(600); +tail = cll.insertAtIndex(50, 1); +tail = cll.insertAtIndex(250, 3); + +console.log(tail); + +cll.removeAt(0); +cll.removeAt(2); + +cll.printCircularLinkedList(tail); +cll.size(); \ No newline at end of file diff --git a/Javascript-DSA/linkedLists/doubleLinkedList.js b/Javascript-DSA/linkedLists/doubleLinkedList.js new file mode 100644 index 00000000..4d46a1b1 --- /dev/null +++ b/Javascript-DSA/linkedLists/doubleLinkedList.js @@ -0,0 +1,156 @@ +class Node { + constructor(data) { + this.data = data; + this.previous = null; + this.next = null; + } + +} + +class DoubleLinkedList { + constructor() { + this.head = null; + this.length = 0; + } + + insertAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + newNode.previous = null; + + if(this.head != null) { + this.head.previous = newNode; + } + this.head = newNode; + this.length++; + } + + insertAtEnd(data) { + let newNode = new Node(data); + + if(this.head == null ){ + this.head = newNode; + this.length++; + } else { + let current = this.head; + while(current.next != null) { + current = current.next; + } + current.next = newNode; + newNode.previous = current; + this.length++; + } + } + insertAtIndex(data, index) { + if(index == 0) { + this.insertAtStart(data); + } + else if(index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let newNode = new Node(data); + let current = this.head; + let count = 0; + while (count < index) { + current = current.next; + count++; + } + newNode.next = current.next; + newNode.previous = current; + newNode.previous.next = newNode; + current = null; + this.length++; + } + } + + + size() { + console.log('Length of Double Linked List is ' + this.length); + } + getLinkedListSize() { + let s = this.head; + let p = null; + let count = 0; + + while(s != null ){ + p = s; + s = s.next; + count++; + } + console.log("count", count); + } + + getElement(index) { + if(index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.head; + let count = 0; + while(current != null) { + if(count == index) { + console.log(current.data); + } + count++; + current = current.next; + } + } + + } + removeAtStart() { + if(this.head == null) { + return false; + } + let currentData = this.head.data; + this.head = this.head.next; + this.head.previous = null; + + this.length--; + console.log(currentData); + } + removeAtEnd(index) { + if(index == 0) { + this.removeAtStart(); + } else if(index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.head; + let count = 0; + while(count < index) { + count++; + current = current.next; + } + if(current.previous != null) { + current.previous.next = current.next; + current.next.previous = current.previous; + } + current = null; + this.length--; + } + } + + + printDoubleLinkedList() { + let current = this.head; + + while(current != null) { + console.log(current); + current = current.next; + } + } + + +} + +const dll = new DoubleLinkedList(); +dll.insertAtStart(100); +dll.insertAtEnd(500); +dll.insertAtEnd(1000); +dll.insertAtEnd(800); +dll.insertAtEnd(600); +dll.insertAtIndex(400, 4); +dll.printDoubleLinkedList(); +dll.size(); +dll.getLinkedListSize(); +dll.removeAtStart(); +dll.getElement(4); + diff --git a/Javascript-DSA/linkedLists/practice.js b/Javascript-DSA/linkedLists/practice.js new file mode 100644 index 00000000..e69de29b diff --git a/Javascript-DSA/linkedLists/reverseSingleLinkedList.js b/Javascript-DSA/linkedLists/reverseSingleLinkedList.js new file mode 100644 index 00000000..733b638b --- /dev/null +++ b/Javascript-DSA/linkedLists/reverseSingleLinkedList.js @@ -0,0 +1,84 @@ +class Node { //! Node class + constructor(data) { + this.data = data; + this.next = null; + } +} +// +class SingleLinkedList { //! linkedlist class + constructor() { + this.head = null; + this.length = 0; + } + //! insert at start + insertElementAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + this.head = newNode; + this.length++; + } + //! insert at end + insertElementAtEnd(data) { + let newNode = new Node(data); //! create a new node + let s = null; //! to keep track of current head + if(this.head == null) { + this.head = newNode; + } + else { + s = this.head; + while(s.next != null) { + s = s.next; + } + s.next = newNode; + } + this.length++; + } + printSingleLinkedList() { + let current = this.head; + while(current) { + console.log(current); + current = current.next; + } + } + + // reverseLinkedList() { + // let prev = null; + // let current = this.head; + // while (current) { + // let following = current.next; + // current.next = prev; + // prev = current; + // current = following; + // } + // let s = prev; + // while(s) { + // console.log(s); + // s = s.next; + // } + // } + + reverseLinkedList() { + let p1 = null; + let p2 = this.head; + // let p3 = this.head; + while(p2) { + const p3 = p2.next; + p2.next = p1; + p1 = p2; + p2 = p3; + } + let s = p1; + while(s) { + console.log(s); + s = s.next; + } + } +} +let singleLinkedList = new SingleLinkedList(); +singleLinkedList.insertElementAtStart(10); +singleLinkedList.insertElementAtEnd(20); +singleLinkedList.insertElementAtEnd(30); +singleLinkedList.insertElementAtEnd(40); +singleLinkedList.reverseLinkedList(); + + diff --git a/Javascript-DSA/linkedLists/singleLinkedList.js b/Javascript-DSA/linkedLists/singleLinkedList.js new file mode 100644 index 00000000..6e842a15 --- /dev/null +++ b/Javascript-DSA/linkedLists/singleLinkedList.js @@ -0,0 +1,115 @@ +class Node { //! Node class + constructor(data) { + this.data = data; + this.next = null; + } +} + +class SingleLinkedList { //! linkedlist class + constructor() { + this.head = null; + this.length = 0; + } + + //! insert at start + insertElementAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + this.head = newNode; + this.length++; + } + //! insert at end + insertElementAtEnd(data) { + let newNode = new Node(data); //! create a new node + let s = null; //! to keep track of current head + if(this.head == null) { + this.head = newNode; + } + else { + s = this.head; + while(s.next != null) { + s = s.next; + } + s.next = newNode; + } + this.length++; + + } + //! insert at index + insertElementAtIndex(data, index) { + //! + if(index == 0) { + this.insertAtStart(data); + } + else if(index < 0 || index >= this.length) + console.log("Array index out of bounds"); + else { + let newNode = new Node(data); + let current, previous; + current = this.head; + let count = 0; + //! traverse till index-1 as linked list has 0 based indexing + while(count < index) { + previous = current; + current = current.next; + count++; + } + newNode.next = current; //! set next of new node to current node. + previous.next = newNode; //! set next of previous node to new node. + current = null; + + } +} +getElement(index) { + if(index < 0 || index>= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.head; + let count = 0; + while(count != index) { + count++; + current = current.next; + } + console.log(current.data); + } + + } + printSingleLinkedList() { + let current = this.head; + while(current) { + console.log(current); + current = current.next; + } + } + size() { + console.log(this.length); + } + + getLinkedListSize() { + let count = 0; + let s = this.head; + let p = null; + + while(s.next != null) { + p = s; + s = s.next; + count++; + } + console.log(count); + + } +} + +let singleLinkedList = new SingleLinkedList(); + +singleLinkedList.insertElementAtStart(10); +singleLinkedList.insertElementAtEnd(20); +singleLinkedList.insertElementAtEnd(30); +singleLinkedList.insertElementAtEnd(40); +singleLinkedList.insertElementAtIndex(50, 3); +singleLinkedList.getElement(3); +singleLinkedList.size(); +singleLinkedList.getLinkedListSize(); + +singleLinkedList.printSingleLinkedList(); + diff --git a/Javascript-DSA/linkedLists/tempCodeRunnerFile.js b/Javascript-DSA/linkedLists/tempCodeRunnerFile.js new file mode 100644 index 00000000..fec24687 --- /dev/null +++ b/Javascript-DSA/linkedLists/tempCodeRunnerFile.js @@ -0,0 +1,12 @@ +getLinkedListSize() { + // let count = 0; + // let s = this.head; + // let p = null; + + // while(s.next != null) { + // p = s; + // s = s.next; + // count++; + // } + // console.log(count); + // } \ No newline at end of file diff --git a/Linked_List/LRU-Cache.js b/Linked_List/LRU-Cache.js new file mode 100644 index 00000000..d694f5c2 --- /dev/null +++ b/Linked_List/LRU-Cache.js @@ -0,0 +1,102 @@ +class LRUCache { + constructor(maxSize) { + this.cache = {}; + this.maxSize = maxSize || 1; + this.currentSize = 0; + this.listOfMostRecent = new DoubleLinkedList(); + } + + //! O(1) time | O(1) space | space depends on maxSize. + insertKeyValuePair(key, value) { + if(!(key in this.cache)) { + if(this.currentSize == this.maxSize) { + this.evictLeastRecent(); + } else { + this.currentSize++; + } + this.cache[key] = new DoubleLinkedListNode(key, value); + } else { + this.replaceKey(key, value); + } + this.updateMostRecent(this.cache[key]); +} + //! O(1) time | O(1) space + getValueFromKey(key) { + if (!(key in this.cache)) return null; + this.updateMostRecent(this.cache[key]); + return this.cache[key].value; + } + + //! O(1) time | O(1) space + getMostRecentKey() { + if(!this.listOfMostRecent.head) return; + return this.listOfMostRecent.head.key; + } + evictLeastRecent() { + const keyToRemove = this.listOfMostRecent.tail.key; + this.listOfMostRecent.removeTail(); + delete this.cache[keyToRemove]; + } + updateMostRecent(node) { + this.listOfMostRecent.setHeadTo(node); + } + + replaceKey(key, value) { + if(!(key in this.cache)) { + throw new Error("This provided key isn't in the cache!"); + } + this.cache[key].value = value; + } +} +class DoubleLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + setHeadTo(node) { + if(this.head == node) { + return; + } else if(this.head == null) { + this.head = node; + this.tail = node; + } else if(this.head == this.tail) { + this.tail.prev = node; + this.head = node; + this.head.next = this.tail; + } else { + if(this.tail == node) this.removeTail(); + node.removeBindings(); + this.head.prev = node; + node.next = this.head; + this.head = node; + } + } + removeTail() { + if(this.tail == null) return; + if(this.tail == this.head) { + this.head = null; + this.tail = null; + return; + } + this.tail = this.tail.prev; + this.tail.next = null; + } + } +class DoubleLinkedListNode { + constructor(key, value) { + this.key = key; + this.value = value; + this.prev = null; + this.next = null; + } + removeBindings() { + if(this.prev != null) { + this.prev.next = this.next; + } + if(this.next != null) { + this.next.prev = this.prev; + } + this.prev = null; + this.next = null; + } +} \ No newline at end of file diff --git a/Linked_List/LinkedListMergeSort.js b/Linked_List/LinkedListMergeSort.js new file mode 100644 index 00000000..ddbfa308 --- /dev/null +++ b/Linked_List/LinkedListMergeSort.js @@ -0,0 +1,59 @@ +function mergeSort(head) { +if(head == null || head.next == null) return head; + + const mid = findMid(head); + let left = head; + let right = mid.next; + mid.next = null; + + left = mergeSort(left); + right = mergeSort(right); + + return mergeTwoLists(left, right); +} + +function findMid(head) { + let slow = head; + let fast = head.next; + + while(fast != null && fast.next == null) { + slow = slow.next; + fast = fast.next.next; + } +} + +function mergeTwoLists(left, right) { + + if(left == null) return right; + if(right == null) return left; + + let dummy = new Node(-1); + + let currentNode = dummy; + + while(left != null && right != null) { + if(left.value < right.value) { + currentNode.next = left; + currentNode = currentNode.next; + left = left.next; + } else { + currentNode.next = right; + currentNode = currentNode.next; + right = right.next; + } + } + + while(left != null) { + currentNode.next = left; + currentNode = currentNode.next; + left = left.next; + } + + while(right != null) { + currentNode.next = right; + currentNode = currentNode.next; + right = right.next; + } + + return dummy.next; +} \ No newline at end of file diff --git a/Linked_List/circularLinkedList.js b/Linked_List/circularLinkedList.js new file mode 100644 index 00000000..3c3e8cb1 --- /dev/null +++ b/Linked_List/circularLinkedList.js @@ -0,0 +1,155 @@ +class Node { + constructor(data) { + this.data = data; + this.next = null; + } +} + +class CircularLinkedList { + constructor() { + this.tail = null; + this.length = 0; + } + + insertToEmpty(tail, data) { + if(this.tail != null) { + return this.tail; + } + let newNode = new Node(data); + this.tail = newNode; + this.tail.next = newNode; + this.length++; + + return this.tail; + } + printCircularLinkedList(tail) { + let current; + + if(tail == null) { + console.log("List is empty"); + return; + } + + current = this.tail.next; + do { + console.log(current.data); + current = current.next; + } while(current != this.tail.next); + } + + size() { + console.log(this.length); + } + + insertAtStart(data) { + if(this.tail == null) { + return this.insertToEmpty(this.tail, data); + } + let newNode = new Node(data); + + newNode.next = this.tail.next; //! set next node of new node to current head. + this.tail.next = newNode; + this.length++; + return this.tail; + } + + insertAtEnd(data) { + if (this.tail == null) { + return this.insertToEmpty(this.tail, data); + } + let newNode = new Node(data); + newNode.next = this.tail.next; + this.tail.next = newNode; + this.tail = newNode; + this.length++; + return this.tail; + } + insertAtIndex(data, index) { + if(index == 0) { + this.insertAtStart(data); + } else if (index < 0 || index >= this.length) { + console.log("Array index out of bounds"); + } else { + let newNode = new Node(data); + let current, previous; + current = this.tail.next; + let count = 0; + while (count < index) { + previous = current; + current = current.next; + count++; + } + newNode.next = current; + previous.next = newNode; + + this.length++; + return this.tail; + } + } + getElement() { + if (index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.tail.next; + let count = 0; + do { + if (count == index && current != null) { + console.log(current.data); + } + count++; + current = current.next; + } while (current != this.tail.next); + } + } + removeAt(index) { + if (index == 0) { + if(this.tail.next != null) { + return false; + } + let current = this.tail.next; + this.tail.next = current.next; + current = null; + + this.length--; + } else if (index < 0 || index >= this.length) { + console.log("Array index out of bounds"); + } else { + let current, previous; + current = this.tail.next; + let count = 0; + while (count < index) { + count++; + previous = current; + current = current.next; + } + previous.next = current.next; + current = null; + this.length--; + + } + } +} + +const cll = new CircularLinkedList(); +// cll.insertAtStart(500); +// cll.insertAtStart(1000); +// cll.insertAtEnd(800); +// cll.insertAtEnd(600); +// cll.insertAtIndex(50, 1); +// cll.insertAtIndex(250, 3); +// cll.printCircularLinkedList(); + +tail = cll.insertAtStart(500); +tail = cll.insertAtStart(1000); +tail = cll.insertAtEnd(800); +tail = cll.insertAtEnd(600); +tail = cll.insertAtIndex(50, 1); +tail = cll.insertAtIndex(250, 3); + +console.log(tail); + +cll.removeAt(0); +cll.removeAt(2); + +cll.printCircularLinkedList(tail); +cll.size(); \ No newline at end of file diff --git a/Linked_List/doubleLinkedList.js b/Linked_List/doubleLinkedList.js new file mode 100644 index 00000000..4d46a1b1 --- /dev/null +++ b/Linked_List/doubleLinkedList.js @@ -0,0 +1,156 @@ +class Node { + constructor(data) { + this.data = data; + this.previous = null; + this.next = null; + } + +} + +class DoubleLinkedList { + constructor() { + this.head = null; + this.length = 0; + } + + insertAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + newNode.previous = null; + + if(this.head != null) { + this.head.previous = newNode; + } + this.head = newNode; + this.length++; + } + + insertAtEnd(data) { + let newNode = new Node(data); + + if(this.head == null ){ + this.head = newNode; + this.length++; + } else { + let current = this.head; + while(current.next != null) { + current = current.next; + } + current.next = newNode; + newNode.previous = current; + this.length++; + } + } + insertAtIndex(data, index) { + if(index == 0) { + this.insertAtStart(data); + } + else if(index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let newNode = new Node(data); + let current = this.head; + let count = 0; + while (count < index) { + current = current.next; + count++; + } + newNode.next = current.next; + newNode.previous = current; + newNode.previous.next = newNode; + current = null; + this.length++; + } + } + + + size() { + console.log('Length of Double Linked List is ' + this.length); + } + getLinkedListSize() { + let s = this.head; + let p = null; + let count = 0; + + while(s != null ){ + p = s; + s = s.next; + count++; + } + console.log("count", count); + } + + getElement(index) { + if(index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.head; + let count = 0; + while(current != null) { + if(count == index) { + console.log(current.data); + } + count++; + current = current.next; + } + } + + } + removeAtStart() { + if(this.head == null) { + return false; + } + let currentData = this.head.data; + this.head = this.head.next; + this.head.previous = null; + + this.length--; + console.log(currentData); + } + removeAtEnd(index) { + if(index == 0) { + this.removeAtStart(); + } else if(index < 0 || index >= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.head; + let count = 0; + while(count < index) { + count++; + current = current.next; + } + if(current.previous != null) { + current.previous.next = current.next; + current.next.previous = current.previous; + } + current = null; + this.length--; + } + } + + + printDoubleLinkedList() { + let current = this.head; + + while(current != null) { + console.log(current); + current = current.next; + } + } + + +} + +const dll = new DoubleLinkedList(); +dll.insertAtStart(100); +dll.insertAtEnd(500); +dll.insertAtEnd(1000); +dll.insertAtEnd(800); +dll.insertAtEnd(600); +dll.insertAtIndex(400, 4); +dll.printDoubleLinkedList(); +dll.size(); +dll.getLinkedListSize(); +dll.removeAtStart(); +dll.getElement(4); + diff --git a/Linked_List/doublyLinkedListConstruction.js b/Linked_List/doublyLinkedListConstruction.js new file mode 100644 index 00000000..e656564a --- /dev/null +++ b/Linked_List/doublyLinkedListConstruction.js @@ -0,0 +1,110 @@ +class Node { + constructor(value) { + this.value = value; + this.prev = null; + this.next = null; + } +} + +class DoubleLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + //! O(1) time | O(1) space + setHead(node) { + if(this.head == null) { + this.head = node; + this.tail = node; + } else { + this.insertBefore(this.head, node); + } + } + //! O(1) time | O(1) space + setTail(node) { + if(this.tail == null) { + this.setHead(node); + } else { + this.insertAfter(this.tail, node); + } + } + //! O(1) time | O(1) space + insertBefore(node, nodeToInsert) { + if(nodeToInsert == this.head && nodeToInsert == this.tail) { + return; + } + this.remove(nodeToInsert); + nodeToInsert.prev = node.prev; + nodeToInsert.next = node; + if(node.prev == null) { + this.head = nodeToInsert; + } + else { + node.prev.next = nodeToInsert; + } + node.prev = nodeToInsert; + } + //! O(1) time | O(1) space + insertAfter(node, nodeToInsert) { + if(nodeToInsert == this.head && nodeToInsert == this.tail) { + return; + } + this.remove(nodeToInsert); + nodeToInsert.prev = node; + nodeToInsert.next = node.next; + if(node.next == null) { + this.tail = nodeToInsert; + } + else { + node.next.prev = nodeToInsert; + } + node.next = nodeToInsert; + } + //! O(p) time | O(1) space where p is position + insertAtPosition(position, nodeToInsert) { + if(position == 1) { + this.setHead(nodeToInsert); + return; + } + let node = this.head; + let currentPosition = 1; + while(node != null && currentPosition++ != position) node = node.next; + if(node != null) { + this.insertBefore(node, nodeToInsert); + } else { + this.setTail(nodeToInsert); + } + } + //! O(n) time | O(1) space + removeNodeWithValue(value) { + let node = this.head; + while(node != null) { + const nodeToRemove = node; //! we traversing till the end of list because there may be many nodes with same value. + node = node.next; + if(nodeToRemove.value == value) { + this.remove(nodeToRemove); + } + } + } + //! O(1) time | O(1) space + remove(node) { + if(node == this.head) this.head = this.head.next; + if(node == this.tail) this.tail = this.tail.prev; + this.removeNodeBindings(node); + } + //! O(n) time | O(1) space + containsNodeWithValue(value) { + let node = this.head; + while(node != null && node.value != value) { + node = node.next; + } + return node != null; + } + //! O(1) time | O(1) space + removeNodeBindings(node) { + if(node.prev != null) node.prev.next = node.next; + if(node.next != null) node.next.prev = node.prev; + node.prev = null; + node.next = null; + } +} \ No newline at end of file diff --git a/Linked_List/dummy1.js b/Linked_List/dummy1.js new file mode 100644 index 00000000..f4b358c8 --- /dev/null +++ b/Linked_List/dummy1.js @@ -0,0 +1,105 @@ +class LRUCache { + constructor(maxSize) { + this.cache = {}; + this.maxSize = maxSize || 1; + this.currentSize = 0; + this.listOfMostRecent = new DoublyLinkedList(); + } + + insertKeyValuePair(key, value) { + if( !(key in this.cache)) { + if(this.currentSize == this.maxSize) { + this.evictLeastRecent(); + } else { + this.currentSize++; + } + this.cache[key] = new DoublyLinkedListNode(key, value); + } else { + this.replaceKey(key, value); + } + this.updateMostRecent(this.cache[key]); + } + getValueFromKey(key) { + if(!(key in this.cache)) { + return null; + } + this.updateMostRecent(this.cache[key]); + return this.cache[key].value; + } + getMostRecentKey() { + if(!this.listOfMostRecent.head) return; + return this.listOfMostRecent.head.key; + } + evictLeastRecent() { + const keyToRemove = this.listOfMostRecent.tail.key; + this.listOfMostRecent.removeTail(); + delete this.cache[keyToRemove]; + } + updateMostRecent(node) { + this.listOfMostRecent.setHeadTo(node); + } + replaceKey(key, value) { + if(!(key in this.cache)) { + throw new Error("The provided key isn't in the cache!"); + } + this.cache[key].value = value; + } +} + +class DoublyLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + + setHeadTo(node) { + if(this.head == node) { + return; + } else if(this.head == null) { + this.head = node; + this.tail = node; + } else if(this.head == this.tail) { + this.tail.prev = node; + this.head = node; + this.head.next = this.tail; + } else { + if(this.tail == node) this.removeTail(); + node.removeBindings(); + this.head.prev = node; + node.next = this.head; + this.head = node; + } + } + removeTail() { + if(this.tail == null) return; + if(this.tail == this.head) { + this.head = null; + this.tail = null; + return; + } + this.tail = this.tail.prev; + this.tail.next = null; + } + } + + class DoublyLinkedListNode { + constructor(key, value) { + this.key = key; + this.value = value; + this.prev = null; + this.next = null; + } + + removeBindings() { + if(this.prev != null) { + this.prev.next = this.next; + } + if(this.next != null) { + this.next.prev = this.prev; + } + this.next = null; + this.prev = null; + } + } +// Do not edit the line below. +exports.LRUCache = LRUCache; diff --git a/Linked_List/dummy2.js b/Linked_List/dummy2.js new file mode 100644 index 00000000..49912f13 --- /dev/null +++ b/Linked_List/dummy2.js @@ -0,0 +1,109 @@ +// Do not edit the class below except for the insertKeyValuePair, +// getValueFromKey, and getMostRecentKey methods. Feel free +// to add new properties and methods to the class. +class LRUCache { + constructor(maxSize) { + this.cache = {}; + this.maxSize = maxSize || 1; + this.currentSize = 0; + this.listOfMostRecent = new DoublyLinkedList(); + } + + insertKeyValuePair(key, value) { + if(!(key in this.cache)) { + if(this.currentSize === this.maxSize) { + this.evictLeastRecent(); + } else { + this.currentSize++; + } + this.cache[key] = new DoublyLinkedListNode(key, value); + } else { + this.replaceKey(key, value); + } + this.updateMostRecent(this.cache[key]); + } + + getValueFromKey(key) { + if(!(key in this.cache)) return null; + this.updateMostRecent(this.cache[key]); + return this.cache[key].value; + } + + getMostRecentKey() { + if(!this.listOfMostRecent.head) return; + return this.listOfMostRecent.head.key; + } + evictLeastRecent() { + const keyToRemove = this.listOfMostRecent.tail.key; + this.listOfMostRecent.removeTail(); + delete this.cache[keyToRemove]; + } + + updateMostRecent(node) { + this.listOfMostRecent.setHeadTo(node); + } + + replaceKey(key, value) { + if(!(key in this.cache)) { + throw new Error("This provided key isn't in the cache!") + } + this.cache[key].value = value; + } +} +class DoublyLinkedList { + constructor() { + this.head = null; + this.tail = null; + } + + setHeadTo(node) { + if(this.head === node) { + return; + } else if(this.head === null) { + this.head = node; + this.tail = node; + } else if(this.head === this.tail) { + this.tail.prev = node; + this.head = node; + this.head.next = this.tail; + } else { + if(this.tail === node) this.removeTail(); + node.removeBindings(); + this.head.prev = node; + node.next = this.head; + this.head = node; + } + } + removeTail() { + if(this.tail === null) return; + if(this.tail === this.head) { + this.head = null; + this.tail = null; + return; + } + this.tail = this.tail.prev; + this.tail.next = null; + } +} + +class DoublyLinkedListNode { + construct(key, value) { + this.key = key; + this.value = value; + this.prev = null; + this.next = null; + } + + removeBindings() { + if(this.prev != null) { + this.prev.next = this.next; + } + if(this.next != null) { + this.next.prev = this.prev; + } + this.prev = null; + this.next = null; + } +} +// Do not edit the line below. +exports.LRUCache = LRUCache; diff --git a/Linked_List/findLoop.js b/Linked_List/findLoop.js new file mode 100644 index 00000000..fdf79030 --- /dev/null +++ b/Linked_List/findLoop.js @@ -0,0 +1,22 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n) time | O(1) space +function findLoop(head) { + let first = head.next; + let second = head.next.next; + + while(first != second) { + first = first.next; + second = second.next.next; + } + first = head; + while(first != second) { + first = first.next; + second = second.next + } + return first; +} \ No newline at end of file diff --git a/Linked_List/flattenLinkedList.js b/Linked_List/flattenLinkedList.js new file mode 100644 index 00000000..6039e00c --- /dev/null +++ b/Linked_List/flattenLinkedList.js @@ -0,0 +1,38 @@ +//! https://www.codingninjas.com/codestudio/problems/1112655 + +function flatten(root) { + if(root == null || root.next == null) return root; + + root.next = flatten(root.next); + + root = mergeLists(root, root.next); + + return root; +} + + +function mergeLists(list1, list2) { + if(list1 == null || list2 == null) return list1 || list2; + + let dummyNode = new Node(0); + let currentNode = dummyNode; + + while(list1 != null && list2 != null) { + if(list1.value < list2.value) { + currentNode.bottom = list1; + currentNode = currentNode.bottom; + list1 = list1.bottom; + } else { + currentNode.bottom = list2; + currentNode = currentNode.bottom; + list2 = list2.bottom; + } + } + + if(list1) currentNode.bottom = list1; + else currentNode.bottom = list2; + + return dummyNode.bottom; +} + + diff --git a/Linked_List/intersectionOfTwoNodes.js b/Linked_List/intersectionOfTwoNodes.js new file mode 100644 index 00000000..0e11183a --- /dev/null +++ b/Linked_List/intersectionOfTwoNodes.js @@ -0,0 +1,14 @@ +// https://leetcode.com/problems/intersection-of-two-linked-lists/ + +function getIntersectionNode (headA, headB) { + + let headANode = headA; + let headBNode = headB; + + while(headANode !== headBNode) { + headANode = headANode === null ? headB : headANode.next; + headBNode = headBNode === null ? headA : headBNode.next; + } + return headANode; +} + diff --git a/Linked_List/linkedListPalindrome.js b/Linked_List/linkedListPalindrome.js new file mode 100644 index 00000000..a2415bb3 --- /dev/null +++ b/Linked_List/linkedListPalindrome.js @@ -0,0 +1,68 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(1) space + +function linkedListPalindrome(head) { + + let fastNode = head; + let slowNode = head; + + while(fastNode != null && fastNode.next != null) { + slowNode = slow.next; + fastNode = fastNode.next.next; + } + + let reversedSecondHalfNode = reverseLinkedList(slowNode); + let firstHalfNode = head; + + while(reversedSecondHalfNode != null) { + if(reversedSecondHalfNode.value != firstHalfNode.value) { + return false; + } + reversedSecondHalfNode = reversedSecondHalfNode.next; + firstHalfNode = firstHalfNode.next; + } + return true; +} + +function reverseLinkedList(head) { + let previousNode = null; + let currentNode = head; + + while(currentNode != null) { + let nextNode = currentNode.next; + currentNode.next = previousNode; + previousNode = currentNode; + currentNode = nextNode; + } + return previousNode; +} + +//! O(n) time | O(n) space +function linkedListPalindrome(head) { + let currentNode = head; + let values = []; + let len = 0; + + while(currentNode != null) { + values[len++] = currentNode.value; + currentNode = currentNode.next; + } + + let i = 0; + let j = values.length - 1; + + while( i < j) { + if(values[i] != values[j]) { + return false; + } + i++; + j--; + } +return true; +} \ No newline at end of file diff --git a/Linked_List/mergeLinkedLists.js b/Linked_List/mergeLinkedLists.js new file mode 100644 index 00000000..faff6740 --- /dev/null +++ b/Linked_List/mergeLinkedLists.js @@ -0,0 +1,53 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n + m) time | O(1) space +function mergeLinkedLists(headOne, headTwo) { + let p1 = headOne; + let p1Prev = null; + let p2 = headTwo; + + while(p1 && p2) { + if(p1.value < p2.value) { + p1Prev = p1; + p1 = p1.next; + } else { + if(!p1Prev) { + p1Prev.next = p2; + p1Prev = p2; + p2 = p2.next; + p1Prev.next = p1; + } + } + } + if(p1 == null) { + p1Prev.next = p2; + } + return headOne.value < headTwo.value ? headOne: headTwo; +} + +//! O(n + m) time | O(n + m) space +function mergeLinkedLists(headOne, headTwo) { + recursiveMerge(headOne, headTwo, null); + return headOne.value < headTwo.value ? headOne: headTwo; +} + +function recursiveMerge(p1, p2, p1Prev) { + if(p1 == null) { + p1Prev.next = p2; + return; + } + if(p2 == null) return; + + if(p1.value < p2.value) { + recursiveMerge(p1.next, p2, p1); + } else { + if(p1Prev != null) p1Prev.next = p2; + const newP2 = p2.next; + p2.next = p1; + recursiveMerge(p1, newP2, p2); + } +} \ No newline at end of file diff --git a/Linked_List/nodeSwap.js b/Linked_List/nodeSwap.js new file mode 100644 index 00000000..96bc5d9a --- /dev/null +++ b/Linked_List/nodeSwap.js @@ -0,0 +1,39 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(n) space +function nodeSwap(head) { + if(head == null || head.next == null) return head; + + const nodeNext = head.next; + + head.next = nodeSwap(head.next.next); + + nodeNext.next = head; + + return nextNode; +} + +//! O(n) time | O(1) space +function nodeSwap(head) { + let tempNode = new LinkedList(0); + tempNode.next = head; + let previousNode = tempNode.prev; + + while(previousNode.next != null && previousNode.next.next != null) { + const firstNode = previousNode.next; + const secondNode = previousNode.next.next; + + firstNode.next = secondNode.next; + secondNode.next = firstNode; + previousNode.next = secondNode; + + previousNode = firstNode; + } + + return tempNode.next; +} \ No newline at end of file diff --git a/Linked_List/oddEvenLinkedList.js b/Linked_List/oddEvenLinkedList.js new file mode 100644 index 00000000..ee5b1e2b --- /dev/null +++ b/Linked_List/oddEvenLinkedList.js @@ -0,0 +1,23 @@ +//! https://leetcode.com/problems/odd-even-linked-list/ + + + +//! O(n) time | O(1) space + +function oddEvenList(head) { + + if(!head) return null; + + let odd = head; + let even = head.next; + let evenHead = even; + + while(even && even.next) { + odd.next = even.next; + odd = odd.next; + even.next = odd.next; + even = even.next; + } + odd.next = evenHead; + return head; +}; \ No newline at end of file diff --git a/Linked_List/practice.js b/Linked_List/practice.js new file mode 100644 index 00000000..e69de29b diff --git a/Linked_List/rearrangeLinkedList.js b/Linked_List/rearrangeLinkedList.js new file mode 100644 index 00000000..0256e640 --- /dev/null +++ b/Linked_List/rearrangeLinkedList.js @@ -0,0 +1,59 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(1) space +function rearrangeLinkedList(head, k) { + let smallerListHead = null; + let smallerListTail = null; + let equalListHead = null; + let equalListTail = null; + let greaterListHead = null; + let greaterListTail = null; + + let node = head; + + while(node != null) { + if(node.value < k) { + [smallerListHead, smallerListTail] = growLinkedList(smallerListHead, smallerListTail, node); + } else if(node.value > k) { + [greaterListHead, greaterListTail] = growLinkedList(greaterListHead, greaterListTail, node); + } else { + [equalListHead, equalListTail] = growLinkedList(equalListHead, equalListTail, node); + } + const prevNode = node; + node = node.next; + prevNode.next = null; + } + const [firstHead, firstTail] = connectLinkedLists(smallerListHead, smallerListTail, equalListHead, equalListTail); + const [finalHead, _] = connectLinkedLists(firstHead, firstTail, greaterListHead, greaterListTail); + return finalHead; +} + +function growLinkedList(head, tail, node) { + let newHead = head; + let newTail = node; + + if(newHead == null) { + newHead = node; + } + if(tail != null) { + tail.next = node; + } + return [newHead, newTail]; +} + +function connectLinkedLists(headOne, tailOne, headTwo, tailTwo) { + + const newHead = headOne == null ? headTwo: headOne; + const newTail = tailTwo == null ? tailOne: tailTwo; + + if(tailOne != null) { + tailOne.next = headTwo; + } + return [newHead, newTail]; + +} \ No newline at end of file diff --git a/Linked_List/removeDuplicatesFromLinkedList.js b/Linked_List/removeDuplicatesFromLinkedList.js new file mode 100644 index 00000000..5b30af13 --- /dev/null +++ b/Linked_List/removeDuplicatesFromLinkedList.js @@ -0,0 +1,21 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n) time | O(1) space +function removeDuplicatesFromLinkedList(linkedList) { + let currentNode = linkedList; + while(currentNode != null) { + let nextDistinctNode = currentNode.next; + while(nextDistinctNode != null && currentNode.value == nextDistinctNode.value) { + const temp = nextDistinctNode; + nextDistinctNode = nextDistinct.next; + temp.next = null; + } + currentNode.next = nextDistinctNode; + currentNode = currentNode.next; + } + return linkedList; +} diff --git a/Linked_List/removeKthNodeFromEnd.js b/Linked_List/removeKthNodeFromEnd.js new file mode 100644 index 00000000..b01188a7 --- /dev/null +++ b/Linked_List/removeKthNodeFromEnd.js @@ -0,0 +1,37 @@ +class Node { + constructor(value) { + this.value = value; + this.next = null; + } +} +class LinkedList { + constructor() { + this.head = null; + } + insertElementAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + this.head = newNode; + } +} + +function removeKthNodeFromEnd(head, k) { + let first = head; + let second = head; + let counter = 1; + while(counter <= k) { + second = second.next; + } + if(second == null) { + let temp = head; + head = head.next; + temp.next = null; + return; + } + while(second.next != null) { + first = first.next; + second = second.next; + } + first.next = first.next.next; +} + diff --git a/Linked_List/reverseInKGroups.js b/Linked_List/reverseInKGroups.js new file mode 100644 index 00000000..59a83a72 --- /dev/null +++ b/Linked_List/reverseInKGroups.js @@ -0,0 +1,33 @@ +//!https://leetcode.com/problems/reverse-nodes-in-k-group/ + +function reverseKGroups(head, k) { + + if(head == null || k == 0) return head; + + let tempNode = new LinkedList(0); + + let previousNode = tempNode; + let currentNode = tempNode; + let nextNode = tempNode; + + let len = 0; + while(currentNode.next != null) { + currentNode = currentNode.next; + len++; + } + + while(len >= k) { + currentNode = previousNode.next; + nextNode = currentNode.next; + + for(let i = 1; i < k; i++) { + currentNode.next = nextNode.next; + nextNode.nextNode = previousNode.next; + previousNode.next = nextNode; + nextNode = currentNode.next; + } + prevNode = currentNode; + len -= k; + } + return tempNode.next; +} \ No newline at end of file diff --git a/Linked_List/reverseLinkedList.js b/Linked_List/reverseLinkedList.js new file mode 100644 index 00000000..6b8607c5 --- /dev/null +++ b/Linked_List/reverseLinkedList.js @@ -0,0 +1,19 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} +//! O(n) time | O(1) space +function reverseLinkedList(head) { + + let previousNode = null; + let currentNode = head; + while(currentNode) { + const nextNode = currentNode.next; + currentNode.next = previousNode; + previousNode = currentNode; + currentNode = nextNode; + } + return previousNode; +} \ No newline at end of file diff --git a/Linked_List/reverseSingleLinkedList.js b/Linked_List/reverseSingleLinkedList.js new file mode 100644 index 00000000..84392c5c --- /dev/null +++ b/Linked_List/reverseSingleLinkedList.js @@ -0,0 +1,68 @@ +class Node { //! Node class + constructor(data) { + this.data = data; + this.next = null; + } +} + +class SingleLinkedList { //! linkedlist class + constructor() { + this.head = null; + this.length = 0; + } + //! insert at start + insertElementAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + this.head = newNode; + this.length++; + } + //! insert at end + insertElementAtEnd(data) { + let newNode = new Node(data); //! create a new node + let s = null; //! to keep track of current head + if(this.head == null) { + this.head = newNode; + } + else { + s = this.head; + while(s.next != null) { + s = s.next; + } + s.next = newNode; + } + this.length++; + } + printSingleLinkedList() { + let current = this.head; + while(current) { + console.log(current); + current = current.next; + } + } + + reverseLinkedList() { + let prev = null; + let current = this.head; + while (current) { + let following = current.next; + current.next = prev; + prev = current; + current = following; + } + let s = prev; + while(s) { + console.log(s); + s = s.next; + } + } + +} +let singleLinkedList = new SingleLinkedList(); +singleLinkedList.insertElementAtStart(10); +singleLinkedList.insertElementAtEnd(20); +singleLinkedList.insertElementAtEnd(30); +singleLinkedList.insertElementAtEnd(40); +singleLinkedList.reverseLinkedList(); + + diff --git a/Linked_List/rotateList.js b/Linked_List/rotateList.js new file mode 100644 index 00000000..277b7dcc --- /dev/null +++ b/Linked_List/rotateList.js @@ -0,0 +1,31 @@ +//!62 https://leetcode.com/problems/rotate-list/ + +function rotateList(head, k) { + + if(head == null) return null; + + let tail = head; + let len = 1; + + while(tail.next != null) { + tail = tail.next; + len++; + } + + tail.next = head; + + k = k % len; + + let currentNode = head; + + let counter = 1; + + while(counter <= len - k - 1) { + currentNode = currentNode.next; + counter++; + } + + const newHead = currentNode.next; + currentNode.next = null; + return newHead; +} \ No newline at end of file diff --git a/Linked_List/shiftLinkedList.js b/Linked_List/shiftLinkedList.js new file mode 100644 index 00000000..e6ef9d5a --- /dev/null +++ b/Linked_List/shiftLinkedList.js @@ -0,0 +1,31 @@ +//! O(n) time | O(1) space + +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +function shiftLinkedList(head, k) { + let listLength = 1; + let listTail = head; + while(listTail.next != null) { + listTail = listTail.next; + listLength++; + } + const offset = Math.abs(k) % listLength; + if(offset == 0) return head; + + const newTailPosition = k > 0 ? listLength - offset : offset; + let newTail = head; + for(let i = 1; i < newTailPosition; i++) { + newTail = newTail.next; + } + + const newHead = newTail.next; + newTail.next = null; + listTail.next = head; + return newHead; + +} diff --git a/Linked_List/singleLinkedList.js b/Linked_List/singleLinkedList.js new file mode 100644 index 00000000..6e842a15 --- /dev/null +++ b/Linked_List/singleLinkedList.js @@ -0,0 +1,115 @@ +class Node { //! Node class + constructor(data) { + this.data = data; + this.next = null; + } +} + +class SingleLinkedList { //! linkedlist class + constructor() { + this.head = null; + this.length = 0; + } + + //! insert at start + insertElementAtStart(data) { + let newNode = new Node(data); + newNode.next = this.head; + this.head = newNode; + this.length++; + } + //! insert at end + insertElementAtEnd(data) { + let newNode = new Node(data); //! create a new node + let s = null; //! to keep track of current head + if(this.head == null) { + this.head = newNode; + } + else { + s = this.head; + while(s.next != null) { + s = s.next; + } + s.next = newNode; + } + this.length++; + + } + //! insert at index + insertElementAtIndex(data, index) { + //! + if(index == 0) { + this.insertAtStart(data); + } + else if(index < 0 || index >= this.length) + console.log("Array index out of bounds"); + else { + let newNode = new Node(data); + let current, previous; + current = this.head; + let count = 0; + //! traverse till index-1 as linked list has 0 based indexing + while(count < index) { + previous = current; + current = current.next; + count++; + } + newNode.next = current; //! set next of new node to current node. + previous.next = newNode; //! set next of previous node to new node. + current = null; + + } +} +getElement(index) { + if(index < 0 || index>= this.length) { + console.log('Array index out of bounds'); + } else { + let current = this.head; + let count = 0; + while(count != index) { + count++; + current = current.next; + } + console.log(current.data); + } + + } + printSingleLinkedList() { + let current = this.head; + while(current) { + console.log(current); + current = current.next; + } + } + size() { + console.log(this.length); + } + + getLinkedListSize() { + let count = 0; + let s = this.head; + let p = null; + + while(s.next != null) { + p = s; + s = s.next; + count++; + } + console.log(count); + + } +} + +let singleLinkedList = new SingleLinkedList(); + +singleLinkedList.insertElementAtStart(10); +singleLinkedList.insertElementAtEnd(20); +singleLinkedList.insertElementAtEnd(30); +singleLinkedList.insertElementAtEnd(40); +singleLinkedList.insertElementAtIndex(50, 3); +singleLinkedList.getElement(3); +singleLinkedList.size(); +singleLinkedList.getLinkedListSize(); + +singleLinkedList.printSingleLinkedList(); + diff --git a/Linked_List/sumOfLinkedLists.js b/Linked_List/sumOfLinkedLists.js new file mode 100644 index 00000000..2be1b13f --- /dev/null +++ b/Linked_List/sumOfLinkedLists.js @@ -0,0 +1,32 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(max(m, n)) time | O(max(m, n)) space +function sumOfLinkedLists(linkedListOne, linkedListTwo) { + const newLinkedListHeadPointer = new LinkedList(0); + let currentNode = newLinkedListHeadPointer; + let carry = 0; + + let nodeOne = linkedListOne; + let nodeTwo = linkedListTwo; + + while(nodeOne != null || nodeTwo != null || carry != 0) { + const valueOne = nodeOne != null ? nodeOne.value: 0; + const valueTwo = nodeTwo != null ? nodeTwo.value: 0; + const sumOfValues = valueOne + valueTwo + carry; + + const newValue = sumOfValues % 10; + const newNode = new LinkedList(newValue); + currentNode.next = newNode; + currentNode = newNode; + + carry = Math.floor(sumOfValues / 10); + nodeOne = nodeOne.next != null ? nodeOne.next: null; + nodeTwo = nodeTwo.next != null ? nodeTwo.next: null; + } + return newLinkedListHeadPointer.next; +} \ No newline at end of file diff --git a/Linked_List/zipLinkedList.js b/Linked_List/zipLinkedList.js new file mode 100644 index 00000000..78140ad4 --- /dev/null +++ b/Linked_List/zipLinkedList.js @@ -0,0 +1,64 @@ +class LinkedList { + constructor(value) { + this.value = value; + this.next = null; + } +} + +//! O(n) time | O(1) space +function zipLinkedList(linkedList) { + if(linkedList.next != null || linkedList.next.next != null) return linkedList; + + const firstHalfHead = linkedList; + const secondHalfHead = splitLinkedList(linkedList); + + const reversedSecondHalfHead = reverseLinkedList(secondHalfHead); + + return combineLinkedLists(firstHalfHead, reversedSecondHalfHead); + +} + +function splitLinkedList(linkedList) { + let slowIterator = linkedList; + let fastIterator = linkedList; + + while(fastIterator != null && fastIterator.next != null) { + slowIterator = slowIterator.next; + fastIterator = fastIterator.next.next; + } + + const secondHalfHead = slowIterator.next; + slowIterator.next = null; + + return secondHalfHead; +} + +function combineLinkedLists(linkedList1, linkedList2) { + let linkedList1Iterator = linkedList1; + let linkedList2Iterator = linkedList2; + + while(linkedList2Iterator) { + let linkedList1IteratorNext = linkedList1Iterator.next; + let linkedList2IteratorNext = linkedList2Iterator.next; + + linkedList1Iterator.next = linkedList2Iterator; + linkedList2Iterator.next = linkedList1IteratorNext; + + linkedList1Iterator = linkedList1IteratorNext; + linkedList2Iterator = linkedList2IteratorNext; + } + return linkedList1; +} + +function reverseLinkedList(head) { + let previousNode = null; + let currentNode = head; + + while(currentNode != null) { + const nextNode = currentNode.next; + currentNode.next = previousNode; + previousNode = currentNode; + currentNode = nextNode; + } + return previousNode; +} \ No newline at end of file diff --git a/Math/AddDigits.java b/Math/AddDigits.java new file mode 100644 index 00000000..b6ff86e6 --- /dev/null +++ b/Math/AddDigits.java @@ -0,0 +1,26 @@ +public class AddDigits { + + public static void main(String[] args){ + int num = 20; +// System.out.println(solve(num)); + /** + * O(1) time + * if (num == 0) return 0; + * if (num % 9 == 0) return 9; + * return num % 9; + * simply + * return num == 0 ? 0 : 1 + (num - 1) % 9; + */ + } + + public static int solve(int num) { + int val = num; + int result = 0; + while(val > 9) { + result = val % 10; + result += val / 10; + val = result; + } + return result; + } +} \ No newline at end of file diff --git a/Math/ArmstrongNumber.java b/Math/ArmstrongNumber.java new file mode 100644 index 00000000..7762eeec --- /dev/null +++ b/Math/ArmstrongNumber.java @@ -0,0 +1,23 @@ +public class ArmstrongNumber { + public static void main(String[] args) { + int n = 153; + System.out.println(isArmstrong(n)); + } + public static Boolean isArmstrong(int n) { + int sum = 0; + int tmp = n; + int length = Integer.toString(n).length(); + while (tmp > 0) { + sum += power(tmp % 10, length); + tmp /= 10; + } + return sum == n; + } + public static int power(int a, int b) { + int res = 1; + for(int i = 0; i < b; i++) { + res *= a; + } + return res; + } +} diff --git a/Math/CountDigits.java b/Math/CountDigits.java new file mode 100644 index 00000000..38a865e1 --- /dev/null +++ b/Math/CountDigits.java @@ -0,0 +1,26 @@ +/** + * Given an integer N , write program to count number of digits in N. + * + * + * Example 1: + * Input: N = 12345 + * Output: 5 + * Explanation: N has 5 digits + */ +public class CountDigits { + public static void main(String[] args) { + int n = 13; + System.out.println(evenlyDivides(n)); + } + public static int evenlyDivides(int n) { + // O(log(N)) time | O(1) space + return (int) Math.ceil(Math.log10(n)); +// int result = 0; +// int num = n; // 23 +// while(num > 0) { +// result += 1; +// num /= 10; +// } +// return result; + } +} diff --git a/Math/DeckOfCards.java b/Math/DeckOfCards.java new file mode 100644 index 00000000..7b58708f --- /dev/null +++ b/Math/DeckOfCards.java @@ -0,0 +1,24 @@ +//https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/ +public class DeckOfCards { + public static void main(String[] args) { + int[] deck = {1,2,3,4,4,3,2,1}; + System.out.println(solve(deck)); + } + public static boolean solve(int[] deck) { + int[] count = new int[10000]; + for(int i: deck) + count[i]++; // get counts; + int g = 0; + for(int c: count) // find gcd of all counts; + if(c > 0) + if(g == 0) + g = c; + else + g = gcd(g, c); + System.out.println(g); + return g > 1; + } + public static int gcd(int x, int y) { + return x == 0 ? y: gcd(y % x, x); + } +} diff --git a/Math/Dummy.java b/Math/Dummy.java new file mode 100644 index 00000000..4aa948be --- /dev/null +++ b/Math/Dummy.java @@ -0,0 +1,17 @@ +public class Dummy { + + public static void main(String[] args) { + solve(20); + } + public static int solve(int num) { + int count = 0; + for(int i = 3; i <= num; i += 2) { + if(num % i != 0) { + count += 1; + System.out.println(i); + } + } + return count; + } +} + diff --git a/Math/EvenAdjacent.java b/Math/EvenAdjacent.java new file mode 100644 index 00000000..57b1ad2e --- /dev/null +++ b/Math/EvenAdjacent.java @@ -0,0 +1,18 @@ +public class EvenAdjacent { + + public static void main(String[] args) { + int arr[] = {1, 2, 3, 4, 5}; + System.out.println(solve(arr)); + } + public static int solve(int arr[]) { + int numOfEven = 0; + int numOfOdd = 0; + for(int i = 0; i < arr.length; i++) { + int num = arr[i]; + if(num % 2 == 0) + numOfEven++; + else numOfOdd++; + } + return Math.min(numOfEven, numOfOdd); + } +} \ No newline at end of file diff --git a/Math/FastPower.java b/Math/FastPower.java new file mode 100644 index 00000000..b55e1350 --- /dev/null +++ b/Math/FastPower.java @@ -0,0 +1,17 @@ +public class FastPower { + + public static void main(String args[]) { + int a = 3; + int n = 20; + int m = 21; + + int result = solve(a, n, m); + System.out.println(result); + } + public static int solve(int a, int n, int m) { + if(n == 1) return a; + if(n % 2 == 0) + return solve(a * a % m, n / 2, m); + else return (a * solve(a * a % m, (n - 1) / 2, m)) % m; + } +} \ No newline at end of file diff --git a/Math/FindAllFactors.java b/Math/FindAllFactors.java new file mode 100644 index 00000000..4b59eb59 --- /dev/null +++ b/Math/FindAllFactors.java @@ -0,0 +1,21 @@ +public class FindAllFactors { +/** + * Scaler Class 04:01:2023 + * */ + public static void main(String[] args) { + int n = 6; + System.out.println(solve(n)); + } + public static int solve(int n) { + int numOfFactors = 0; + + for(int i = 1; i * i <=n;) { + if( n % i == 0) { + if( i != n / i) numOfFactors += 2; + else numOfFactors += 1; + } + i++; + } + return numOfFactors; + } +} diff --git a/Math/FindPerfectNumber.java b/Math/FindPerfectNumber.java new file mode 100644 index 00000000..9ab0b463 --- /dev/null +++ b/Math/FindPerfectNumber.java @@ -0,0 +1,22 @@ + +public class FindPerfectNumber { + /** + * Scaler Homework 04 jan 2023 + */ + public static void main(String[] args) { + System.out.println(solve(2)); + } + + public static int solve(int num) { + int sum = 0; + int i = 1; + while( i < num ) { + if( num % i == 0) { + sum += i; + } + i++; + } + if(sum == num) return 1; + return 0; + } +} diff --git a/Math/FindSquareRoot.java b/Math/FindSquareRoot.java new file mode 100644 index 00000000..4e0e57f8 --- /dev/null +++ b/Math/FindSquareRoot.java @@ -0,0 +1,11 @@ +public class FindSquareRoot { + public static void main(String[] args) { + int n = 2987712; + System.out.println(solve(n)); + } + public static int solve(int n) { + int i = 1; + while (i * i <= n) i++; + return i - 1; + } +} diff --git a/Math/GCD.java b/Math/GCD.java new file mode 100644 index 00000000..82295356 --- /dev/null +++ b/Math/GCD.java @@ -0,0 +1,10 @@ +public class GCD { + public static void main(String[] args) { + int x = 2; + int y = 7; + System.out.println(gcd(x, y)); + } + public static int gcd(int x, int y) { + return x == 0 ? y: gcd(y % x, x); + } +} diff --git a/Math/LcmAndGcd.java b/Math/LcmAndGcd.java new file mode 100644 index 00000000..8440e36f --- /dev/null +++ b/Math/LcmAndGcd.java @@ -0,0 +1,22 @@ +import java.util.Arrays; + +public class LcmAndGcd { + public static void main(String[] args) { + long A = 5; + long B = 10; + System.out.println(Arrays.toString(solve(A, B))); + } + public static Long[] solve(Long A, Long B) { + Long ans[] = new Long[2]; + Long t1 = A; + Long t2 = B; + while(t1 % t2 != 0) { //GCD + Long rem = t1 % t2; + t1 = t2; + t2 = rem; + } + ans[1] = t2; //GCD + ans[0] = (A * B) / ans[1]; //LCM Formula: (n1 * n2) / gcd + return ans; + } +} diff --git a/Math/MaxMod.java b/Math/MaxMod.java new file mode 100644 index 00000000..a0882520 --- /dev/null +++ b/Math/MaxMod.java @@ -0,0 +1,25 @@ +public class MaxMod { + public static void main(String[] args) { + + int A[] = {1, 2, 44, 3}; + System.out.println(solve(A)); + } + public static int solve(int arr[]) { + + int firstMax = Integer.MIN_VALUE; + int secondMax = Integer.MIN_VALUE; + + for(int i = 0; i < arr.length; i++) { + int num = arr[i]; + if(num > firstMax) { + secondMax = firstMax; + firstMax = num; + } + if(num > secondMax && num != firstMax) + secondMax = num; + } + System.out.println(firstMax + "," + secondMax); + if(firstMax == Integer.MIN_VALUE || secondMax == Integer.MIN_VALUE) return 0; + return secondMax % firstMax; + } +} \ No newline at end of file diff --git a/Math/PalindromeNumber.java b/Math/PalindromeNumber.java new file mode 100644 index 00000000..b28c6d6a --- /dev/null +++ b/Math/PalindromeNumber.java @@ -0,0 +1,20 @@ +// https://leetcode.com/problems/palindrome-number +public class PalindromeNumber { + /** + * O(log(N)) time base 10. We divided the input by 10 for every iteration + * + * O(1) space + */ + public static void main(String[] args) { + int x = 123; + System.out.println(solve(x)); + } + public static Boolean solve(int x) { + int tmp = x, cache = 0; + while(tmp > 0) { + cache = cache * 10 + tmp % 10; + tmp /= 10; + } + return x > 0 && cache == x; + } +} diff --git a/Math/PerfectSquare.java b/Math/PerfectSquare.java new file mode 100644 index 00000000..40d2d215 --- /dev/null +++ b/Math/PerfectSquare.java @@ -0,0 +1,22 @@ +public class PerfectSquare { + /** + * Scaler class 4 jan 2023 + */ + + public static void main(String[] args) { + int num = 84630800; +// System.out.println(solve1(num)); + System.out.println(solve2(num)); + } + public static int solve1(int num) { + int sr = (int)Math.sqrt(num); + if(sr * sr == num) return sr; + return -1; + } + public static int solve2(int num) { + for(int i = 1; i * i <= num; i++) { + if (i * i == num) return i; + } + return -1; + } +} diff --git a/Math/PrimeNumbers.java b/Math/PrimeNumbers.java new file mode 100644 index 00000000..0c0ce080 --- /dev/null +++ b/Math/PrimeNumbers.java @@ -0,0 +1,29 @@ +import java.util.ArrayList; + +public class PrimeNumbers { + + public static void main(String[] args) { + int num = 100; + + System.out.println(solve(num)); + } + + public static ArrayList solve(int num) { + + ArrayList result = new ArrayList<>(); + for(int val = 1; val <= num; val++) { + if(isPrime(val)) result.add(val); + } + return result; + } + + public static boolean isPrime(int num) { + + if(num < 2) return false; + + for(int idx = 2; idx <= Math.sqrt(num); idx++){ + if(num % idx == 0) return false; + } + return true; + } +} diff --git a/Math/PrintAllDivisors.java b/Math/PrintAllDivisors.java new file mode 100644 index 00000000..8a2ebac3 --- /dev/null +++ b/Math/PrintAllDivisors.java @@ -0,0 +1,13 @@ +// https://practice.geeksforgeeks.org/problems/sum-of-all-divisors-from-1-to-n4738/1 +public class PrintAllDivisors { + public static void main(String[] args) { + int n = 4; + solve(n); + } + public static void solve(int n) { + for(int i = 1; i <= n; i++) { + if(n % i == 0) System.out.print(i + " "); + } + System.out.println(); + } +} diff --git a/Math/ReverseNumber.java b/Math/ReverseNumber.java new file mode 100644 index 00000000..aefd8f44 --- /dev/null +++ b/Math/ReverseNumber.java @@ -0,0 +1,27 @@ +// https://leetcode.com/problems/reverse-integer/ +public class ReverseNumber { + public static void main(String[] args) { + int x = -123; + System.out.println(solve(x)); + } + public static int solve(int x) { + /** + * pop operation: + * pop = x % 10; + * x /= 10; + * + * push operation: + * temp = rev * 10 + pop; + * rev = temp; + */ + int reverse = 0; + while(x != 0) { + int pop = x % 10; + x /= 10; + if(reverse > Integer.MAX_VALUE/10 || (reverse == Integer.MAX_VALUE / 10 && pop > 7)) return 0; + if(reverse < Integer.MIN_VALUE/10 || (reverse == Integer.MIN_VALUE / 10 && pop < -8)) return 0; + reverse = reverse * 10 + pop; + } + return reverse; + } +} diff --git a/Math/SieveOfEratosthenes.java b/Math/SieveOfEratosthenes.java new file mode 100644 index 00000000..0780e7ab --- /dev/null +++ b/Math/SieveOfEratosthenes.java @@ -0,0 +1,47 @@ +import java.util.ArrayList; +import java.util.Arrays; + +public class SieveOfEratosthenes { + public static void main(String[] args) { + System.out.println(solve(100)); + } + + public static ArrayList solve(int num) { + boolean[] prime = new boolean[num + 1]; + ArrayList result = new ArrayList<>(); + Arrays.fill(prime, true); + + for (int p = 2; p * p <= num; p++) { + + // If prime[p] is not changed, then it is prime. + if (prime[p] == true) { + + // Update all multiples of p greater than or equal to the square of it. + // numbers which are multiple of p and are less than p^2 are already been marked. + for (int i = p * p; i <= num; i += p) + prime[i] = false; +// + } + } + for (int p = 2; p <= num; p++) { + if (prime[p]) result.add(p); + } + return result; + } + + /** + * boolean[] notPrime = new boolean[n]; + * int count = 0; + * for (int i = 2; i < n; i++) { + * if (notPrime[i] == false) { + * count++; + * for (int j = 2; i*j < n; j++) { + * notPrime[i*j] = true; + * } + * } + * } + * + * return count; + * } + */ +} diff --git a/Math/moduloArithmetic.java b/Math/moduloArithmetic.java new file mode 100644 index 00000000..355e0e06 --- /dev/null +++ b/Math/moduloArithmetic.java @@ -0,0 +1,40 @@ +public class moduloArithmetic { + public static void main(String[] args) { + int a = 2147483647; + int b = 2; + + System.out.println((a + b) % 5); + + /** + * ADDITION + * (a + b) % c = (a % c + b %c) % c + * + * SUBTRACTION + * (a-b) % c = (a % c - b % c) % c + * + * MULTIPLICATION + * (a * b) % c = (a % c * b % c) % c + * + * DIVISION --> Inverse Modulo + * (a + b) % c(5) = ? + * + * (2147483647 + 2) % 5 = 2147483647 % 5 = 4 + * + * (a + b) % c = (a % c + b %c) % c + * a = c * quotient1(q1)+ reminder1(r1) + * a = c * quotient2(q2) + reminder2(r2) + * + * LHS + *(a + b) % c | REPLACE a && b values + * (c * q1 + r1 + c * q2 + r2) % c + * (c * (q1 + q2) + r1 + r2) % c // (c * (q1 + q2) == c + * (r1 + r2) % c + * + * RHS + * (a % c + b %c) % c | REPLACE a && b values + * ((c * q1 + r1) % c + (c * q2 + r2) % c ) % c + * (r1 + r2 ) % c + * */ + System.out.println(((a % 5) + (b % 5) % 5)); + } +} \ No newline at end of file diff --git a/Patterns/Pattern1.java b/Patterns/Pattern1.java new file mode 100644 index 00000000..6edb1030 --- /dev/null +++ b/Patterns/Pattern1.java @@ -0,0 +1,19 @@ +package Patterns; + +//TODO https://practice.geeksforgeeks.org/problems/square-pattern +public class Pattern1 { + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = 0; i < n; i++) { + String pattern = ""; + for(int j = 0; j < n; j++) { + if(j != n) pattern += "* "; + else pattern += "*"; + } + System.out.println(pattern); + } + } +} diff --git a/Patterns/Pattern10.java b/Patterns/Pattern10.java new file mode 100644 index 00000000..3d619b6d --- /dev/null +++ b/Patterns/Pattern10.java @@ -0,0 +1,27 @@ +package Patterns; + +public class Pattern10 { + //https://practice.geeksforgeeks.org/problems/triangle-pattern-1661718013/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_10 + public static void main(String[] args) { + int i = 10; + solve(i); + } + public static void solve(int n) { + for(int i = 1; i <= n; i++) { + for(int j = 1; j <= i; j++) { + if(j == i) + System.out.print("*"); + else + System.out.print("* "); + } + System.out.println(); + } + for(int i = n - 1; i > -1; i--) { + for(int j = 0; j < i; j++) { + System.out.print("* "); + } + System.out.println(); + } + } +} + diff --git a/Patterns/Pattern11.java b/Patterns/Pattern11.java new file mode 100644 index 00000000..58267d9e --- /dev/null +++ b/Patterns/Pattern11.java @@ -0,0 +1,16 @@ +package Patterns; +// https://practice.geeksforgeeks.org/problems/triangle-pattern-1661718455/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_11 +public class Pattern11 { + public static void main(String[] args) { + int i = 5; + solve(i); + } + public static void solve(int n) { + for (int i = 1; i <= n; i++) { + for(int j = 0; j < i; j++) { + System.out.print( (i + j) % 2 + " "); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern12.java b/Patterns/Pattern12.java new file mode 100644 index 00000000..c9e63948 --- /dev/null +++ b/Patterns/Pattern12.java @@ -0,0 +1,18 @@ +package Patterns; + +public class Pattern12 { + //https://practice.geeksforgeeks.org/problems/double-triangle-pattern-1662664259/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_12 + public static void main(String[] args) { + int n = 4; + solve(n); + } + public static void solve(int n) { + + for(int i = 1; i <= n; i++) { + for(int j = 1; j <= i; j++) System.out.print(j); + for(int k = 2 * (n - i); k > 0; k--) System.out.print(" "); + for(int l = i; l >= 1; l--) System.out.print(l); + System.out.println(); + } + } +} diff --git a/Patterns/Pattern13.java b/Patterns/Pattern13.java new file mode 100644 index 00000000..bcb335c4 --- /dev/null +++ b/Patterns/Pattern13.java @@ -0,0 +1,17 @@ +package Patterns; + +public class Pattern13 { + //https://practice.geeksforgeeks.org/problems/triangle-pattern-1661718712/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_13 + + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + int k = 0; + for(int i = 1; i <= n; i++) { + for(int j = 1; j <= i; j++) System.out.print(++k + " "); + System.out.println(); + } + } +} diff --git a/Patterns/Pattern14.java b/Patterns/Pattern14.java new file mode 100644 index 00000000..eda6e18a --- /dev/null +++ b/Patterns/Pattern14.java @@ -0,0 +1,17 @@ +package Patterns; + +public class Pattern14 { + //https://practice.geeksforgeeks.org/problems/triangle-pattern-1662284916/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_14 + public static void main(String[] args) { + int i = 5; + solve(i); + } + public static void solve(int k) { + for(int i = 1; i <= k; i++) { + for(int j = 65; j < 65 + i; j++) { + System.out.print((char) j +" "); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern15.java b/Patterns/Pattern15.java new file mode 100644 index 00000000..277ad850 --- /dev/null +++ b/Patterns/Pattern15.java @@ -0,0 +1,17 @@ +package Patterns; + +public class Pattern15 { + // https://practice.geeksforgeeks.org/problems/triangle-pattern-1662285196/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_15 + public static void main(String[] args) { + int i = 5; + solve(i); + } + public static void solve(int num) { + for(int i = num; i > -1; i--) { + for(int j = 65; j < 65 + i; j++) { + System.out.print( (char) j + " "); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern16.java b/Patterns/Pattern16.java new file mode 100644 index 00000000..5a6301ed --- /dev/null +++ b/Patterns/Pattern16.java @@ -0,0 +1,19 @@ +package Patterns; + +public class Pattern16 { + //https://practice.geeksforgeeks.org/problems/triangle-pattern-1662285334/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_16 + public static void main(String[] args) { + int i = 5; + solve(i); + } + public static void solve(int num) { + for(int i = 1; i <= num; i++) { + int ascii = 64 + i; + for(int j = 1; j <= i; j++) { + System.out.print( (char) ascii + " "); + } + System.out.println(); + } + + } +} diff --git a/Patterns/Pattern17.java b/Patterns/Pattern17.java new file mode 100644 index 00000000..471c6c15 --- /dev/null +++ b/Patterns/Pattern17.java @@ -0,0 +1,25 @@ +package Patterns; + +public class Pattern17 { + //https://practice.geeksforgeeks.org/problems/triangle-pattern-1662285911/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_17 + public static void main(String[] args) { + int i = 4; + solve(i); + } + public static void solve(int num) { + for(int i = 1; i <= num; i++) { + for(int j = i; j < num; j++) { + System.out.print(" "); + } + int ascii = 65; + for(int k = num - i; k < num; k++) { + System.out.print( (char) ascii++); + } + --ascii; + for(int l = 1; l < i; l++) { + System.out.print( (char) --ascii); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern18.java b/Patterns/Pattern18.java new file mode 100644 index 00000000..c567d944 --- /dev/null +++ b/Patterns/Pattern18.java @@ -0,0 +1,22 @@ +package Patterns; + +public class Pattern18 { + //https://practice.geeksforgeeks.org/problems/triangle-pattern-1662286302/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_18 + public static void main(String[] args) { + int i = 4; + solve(i); + } + + public static void solve(int num) { + + for(int i = 1; i <= num; i++) { + int ascii = 69; + ascii -= i; + for(int j = 1; j <= i; j++) { + ascii += 1; + System.out.print( (char) ascii + " "); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern19.java b/Patterns/Pattern19.java new file mode 100644 index 00000000..803a9f18 --- /dev/null +++ b/Patterns/Pattern19.java @@ -0,0 +1,56 @@ +package Patterns; + +public class Pattern19 { + //https://practice.geeksforgeeks.org/problems/double-triangle-pattern/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_19 + public static void main(String[] args) { + int i = 5; + solve(i); + } + public static void solve(int n) { + + // upper half + for(int i = n; i >= 1; i--) { + + // Star + for(int j = 1; j <= i; j++) { + System.out.print("*"); + } + // Spaces + for(int j = 1; j <= 2*(n-i); j++){ + System.out.print(" "); + } + + //Star + + for(int j = 1; j <= i; j++){ + + System.out.print("*"); + + } + + System.out.println(); + } + + // Lower Half + for(int i = 1; i <= n; i++){ + // Star + for(int j = 1; j <= i; j++){ + System.out.print("*"); + } + + // Spaces + for(int j = 1; j <= 2*(n-i); j++){ + System.out.print(" "); + + } + //Star + for(int j = 1; j <= i; j++){ + System.out.print("*"); + + } + System.out.println(); + + } + + } +} diff --git a/Patterns/Pattern2.java b/Patterns/Pattern2.java new file mode 100644 index 00000000..fe9acd80 --- /dev/null +++ b/Patterns/Pattern2.java @@ -0,0 +1,30 @@ +package Patterns; + +public class Pattern2 { + public static void main(String[] args) { + int n = 5; +// solve(n); + solve1(n); + } + public static void solve(int n) { + String star = "*"; + int idx = 0; + while(idx < n) { + System.out.println(star); + if(idx == n - 1) star += "*"; + else star += " *"; + idx++; + } + } + public static void solve1(int n) { + for(int i = 0; i < n; i++) { + for(int j = 0; j <= i; j++) { + if(j == i) + System.out.print("*"); + else + System.out.print("* "); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern20.java b/Patterns/Pattern20.java new file mode 100644 index 00000000..1fd28730 --- /dev/null +++ b/Patterns/Pattern20.java @@ -0,0 +1,36 @@ +package Patterns; + +public class Pattern20 { +// https://practice.geeksforgeeks.org/problems/double-triangle-pattern-1662287416/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_20 + public static void main(String[] args) { + + int i = 5; + solve(i); + } + public static void solve(int num) { + for(int i = 1; i <= num; i++) { + for(int j = 1; j <= i; j++) { + System.out.print("*"); + } + for(int k = (num - i) * 2; k >= 1; k--) { + System.out.print(" "); + } + for(int l = 1; l <= i; l++) { + System.out.print("*"); + } + System.out.println(); + } + for(int i = num - 1; i >= 1; i--) { + for(int j = 1; j <= i; j++) { + System.out.print("*"); + } + for(int k = 2 * (num - i); k >= 1; k--) { + System.out.print(" "); + } + for(int l = i; l >=1; l--) { + System.out.print("*"); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern21.java b/Patterns/Pattern21.java new file mode 100644 index 00000000..aa058d13 --- /dev/null +++ b/Patterns/Pattern21.java @@ -0,0 +1,21 @@ +package Patterns; + +public class Pattern21 { + //https://practice.geeksforgeeks.org/problems/square-pattern-1662287714/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_21 + public static void main(String[] args) { + int i = 5; + solve(i); + } + public static void solve(int n) { + for(int i = 1; i <= n; i++) { + for (int j = 1; j <= n; j++) { + if(i == 1 || j == 1 || i == n || j == n) { + System.out.print("*"); + } else { + System.out.print(" "); + } + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern22.java b/Patterns/Pattern22.java new file mode 100644 index 00000000..6b2c819c --- /dev/null +++ b/Patterns/Pattern22.java @@ -0,0 +1,19 @@ +package Patterns; + +public class Pattern22 { + //https://practice.geeksforgeeks.org/problems/square-pattern-1662666141/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_22 + public static void main(String[] args) { + int i = 4; + solve(i); + } + public static void solve(int num) { + for(int i = 1; i < 2 * num; i++) { + for(int j = 1; j < 2 * num; j++) { + System.out.print( + Math.max(Math.abs(num - i) + 1, Math.abs(num - j) + 1) + " " + ); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern3.java b/Patterns/Pattern3.java new file mode 100644 index 00000000..584e9fc0 --- /dev/null +++ b/Patterns/Pattern3.java @@ -0,0 +1,20 @@ +package Patterns; + +// https://practice.geeksforgeeks.org/problems/triangle-number +public class Pattern3 { + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = 1; i <= n; i++) { + for(int j = 1; j <= i; j++) { + if(j == i) + System.out.print(j); + else + System.out.print(j + " "); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern4.java b/Patterns/Pattern4.java new file mode 100644 index 00000000..0ebdbcbc --- /dev/null +++ b/Patterns/Pattern4.java @@ -0,0 +1,19 @@ +package Patterns; +//https://practice.geeksforgeeks.org/problems/triangle-number-1661428795/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_4 +public class Pattern4 { + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = 1; i <= n; i++) { + for(int j = 1; j <= i; j++) { + if(j == i) + System.out.print(i); + else + System.out.print(i + " "); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern5.java b/Patterns/Pattern5.java new file mode 100644 index 00000000..8c9824d4 --- /dev/null +++ b/Patterns/Pattern5.java @@ -0,0 +1,16 @@ +package Patterns; +// https://practice.geeksforgeeks.org/problems/triangle-pattern/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_5 +public class Pattern5 { + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = n; i > -1; i--) { + for(int j = 0; j < i; j++) { + System.out.print("*"); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern6.java b/Patterns/Pattern6.java new file mode 100644 index 00000000..4efe8f9b --- /dev/null +++ b/Patterns/Pattern6.java @@ -0,0 +1,16 @@ +package Patterns; +// https://practice.geeksforgeeks.org/problems/triangle-pattern/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_5 +public class Pattern6 { + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = n; i > -1; i--) { + for(int j = 1; j <= i; j++) { + System.out.print(j); + } + System.out.println(); + } + } +} diff --git a/Patterns/Pattern7.java b/Patterns/Pattern7.java new file mode 100644 index 00000000..f261b5d8 --- /dev/null +++ b/Patterns/Pattern7.java @@ -0,0 +1,17 @@ +package Patterns; +// https://practice.geeksforgeeks.org/problems/triangle-pattern-1661492263/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_7 +public class Pattern7 { + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = 1; i <= n; i++) { + for(int l = i; l < n; l++) + System.out.print(" "); + for(int j = 1; j <= (2 * i) - 1; j++) + System.out.print("*"); + System.out.println(); + } + } +} diff --git a/Patterns/Pattern8.java b/Patterns/Pattern8.java new file mode 100644 index 00000000..f05ef081 --- /dev/null +++ b/Patterns/Pattern8.java @@ -0,0 +1,18 @@ +package Patterns; + +// https://practice.geeksforgeeks.org/problems/triangle-pattern-1661493231/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_8 +public class Pattern8 { + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = n; i >= 1; i--) { + for(int k = i; k < n; k++) System.out.print(" "); + for(int j = 1; j <= 2 * i - 1; j++) + System.out.print("*"); + System.out.println(); + } + } + +} diff --git a/Patterns/Pattern9.java b/Patterns/Pattern9.java new file mode 100644 index 00000000..659e3a16 --- /dev/null +++ b/Patterns/Pattern9.java @@ -0,0 +1,24 @@ +package Patterns; +// https://practice.geeksforgeeks.org/problems/pattern/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_9 +public class Pattern9 { + //https://practice.geeksforgeeks.org/problems/pattern/1?utm_source=youtube&utm_medium=collab_striver_ytdescription&utm_campaign=pattern_9 + public static void main(String[] args) { + int n = 5; + solve(n); + } + public static void solve(int n) { + for(int i = 1; i <= n; i++) { + for(int l = i; l < n; l++) + System.out.print(" "); + for(int j = 1; j <= (2 * i) - 1; j++) + System.out.print("*"); + System.out.println(); + } + for(int i = n; i >= 1; i--) { + for(int k = i; k < n; k++) System.out.print(" "); + for(int j = 1; j <= 2 * i - 1; j++) + System.out.print("*"); + System.out.println(); + } + } +} diff --git a/Patterns/pattern1.js b/Patterns/pattern1.js new file mode 100755 index 00000000..ea8b7365 --- /dev/null +++ b/Patterns/pattern1.js @@ -0,0 +1,8 @@ + +for (let row = 1; row < 6; row++) { + let j = ""; + for (let col = 1; col<6; col++){ + j = j + col + " "; + } + console.log(j); +} diff --git a/Patterns/pattern2.js b/Patterns/pattern2.js new file mode 100755 index 00000000..8035e823 --- /dev/null +++ b/Patterns/pattern2.js @@ -0,0 +1,7 @@ +for (let row = 1; row < 6; row++) { + let j = ""; + for (let col = 1; col <= row; col++){ + j = j + col + " "; + } + console.log(j); +} diff --git a/Patterns/pattern3.js b/Patterns/pattern3.js new file mode 100755 index 00000000..b31aec0d --- /dev/null +++ b/Patterns/pattern3.js @@ -0,0 +1,7 @@ +for (let row = 1; row <= 7; row++) { + let j = ""; + for (let col = 1; col <= row; col++){ + j = j + "* "; + } + console.log(j); +} diff --git a/Patterns/pattern4.js b/Patterns/pattern4.js new file mode 100755 index 00000000..6e1a56f3 --- /dev/null +++ b/Patterns/pattern4.js @@ -0,0 +1,31 @@ +let n = 11; +let row = 0; + +//? Upper Part +for (row; row <= Math.floor(n/2); row++) { + + let result = ""; + for (let spaces = 0; spaces < (n - (2*row + 1)); spaces++) { + result = result + " "; + } + + for (let stars = 0; stars < (2*row) + 1; stars++) { + result = result + "* "; + } + console.log(result); +} + +//? Lower Part + +for (row; row < n; row++) { + + let result = ""; + + for (let spaces = 0; spaces < (n - (2*(n - row) - 1)); spaces++) { + result = result + " "; + } + for (let stars = 0; stars < (2*(n - row) - 1); stars++) { + result = result + "* "; + } + console.log(result); +} \ No newline at end of file diff --git a/Patterns/pattern5.js b/Patterns/pattern5.js new file mode 100755 index 00000000..71298daf --- /dev/null +++ b/Patterns/pattern5.js @@ -0,0 +1,18 @@ +let n = 4; +let row = 1; + +for (row; row <= n; row++) { + + let result = ""; + for (let spaces = 1; spaces <= 2*(n - row); spaces++) { + result = result + " "; + } +for (let i = 1; i <= row; i++ ) { + result = result + i + " "; +} +for (let j = row - 1; j >= 1; j-- ) { + result = result + j + " "; +} + console.log(result); + +} diff --git a/Patterns/pattern6.js b/Patterns/pattern6.js new file mode 100755 index 00000000..815b5369 --- /dev/null +++ b/Patterns/pattern6.js @@ -0,0 +1,32 @@ +let n = 11; +let row = 0; + +for (row; row <= Math.floor(n/2); row++) { + let result = ""; + + for (let spaces = 0; spaces < (n - (2*row + 1)); spaces++) { + result = result + " "; + } + for (let i = 1; i <= row+1; i++) { + result = result + i + " "; + } + for (let j = row; j >= 1; j-- ) { + result = result + j + " "; +} + console.log(result); +} +for (row; row < n; row++) { + + let result = ""; + + for (let spaces = 0; spaces < (n - (2*(n - row) - 1)); spaces++ ) { + result = result + " "; + } + for (let i = 1; i <= (n - row ); i++) { + result = result + i + " "; + } + for (let i = ((n - row) - 1); i > 0; i--) { + result = result + i + " "; + } + console.log(result); +} \ No newline at end of file diff --git a/Patterns/pattern7.js b/Patterns/pattern7.js new file mode 100755 index 00000000..4b3fbe26 --- /dev/null +++ b/Patterns/pattern7.js @@ -0,0 +1,20 @@ +let n = 4; +let row = 1; +let i = 0; + +for (row; row <= n; row++) { + + let result = ""; + for (let spaces = 1; spaces <= 2*(n - row); spaces++) { + result = result + " "; + } +for (i ; i < row; i++ ) { + result = result + (i+1) + " "; +} +// i = i-1; +// for (let j = row - 1; j >= 1; j-- ) { +// result = result + j + " "; +// } + console.log(result); + +} diff --git a/Queues/.DS_Store b/Queues/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/Queues/.DS_Store differ diff --git a/Queues/deque.js b/Queues/deque.js new file mode 100644 index 00000000..9d5085c2 --- /dev/null +++ b/Queues/deque.js @@ -0,0 +1,83 @@ +//! Double ended queue +//! 10/02/2022 +class Deque { + constructor() { + this.data = []; + this.front = 0; + this.rear = 0; + + } + + isEmpty() { + return (this.rear - this.front == 0); + } + + addBack(element) { + this.data[this.rear] = element; + this.rear++; + + } + + addFront(element) { + if(this.isEmpty()) { + this.addBack(element); + } + else if(this.front == 0) { + let arr = new Array(2 * (this.rear - this.front)); + let i = arr.length - 1; + let j = this.rear - 1; + + while(j >= this.front) { + arr[i] = this.data[j]; + i--; + j--; + } + this.front = i; + this.rear = arr.length; + this.data = arr; + this.data[this.front] = element; + } + else { + this.front--; + this.data[this.front] = element; + + } + } + + + removeFront() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + return undefined; + } + + removeBack() { + if(!this.isEmpty()) { + let temp = this.data[this.rear - 1]; + this.rear--; + return temp; + } + return undefined; + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +const dequeue = new Deque(); + +dequeue.addBack(10); +dequeue.addBack(20); +dequeue.addFront(30); +console.log(dequeue.getFront()); +dequeue.removeBack(); +dequeue.removeFront(); +console.log(dequeue.getFront()); +dequeue.addFront(100); +console.log(dequeue.getFront()); \ No newline at end of file diff --git a/Queues/largestRectangleInHistogram.js b/Queues/largestRectangleInHistogram.js new file mode 100644 index 00000000..629d8333 --- /dev/null +++ b/Queues/largestRectangleInHistogram.js @@ -0,0 +1,67 @@ +//! 10/02/2022 + +function nextSmaller(array) { + + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = 0; i < array.length; i++) { + + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = i; + + } + stack.push(i); + } + for(let i = 0; i < result.length; i++) { + if(result[i] == - 1) { + result[i] = result.length; + } + } + return result; +} + +function prevSmaller(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = array.length - 1; i >= 0; i--) { + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = i; + } + stack.push(i); + } + + + return result; +} + +function findArea(length, breadth) { + return length * breadth; +} +function maxArea(array) { + + let prev = prevSmaller(array); + // console.log(prev); + let next = nextSmaller(array); + // console.log(next); + let max = 0; + + for(let i = 0; i < array.length; i++) { + + let prevSmallIndex = prev[i]; + let nextSmallIndex = next[i]; + let width = nextSmallIndex - prevSmallIndex - 1; + let area = findArea(array[i], width); + max = Math.max(max, area); + + } + return max; + +} + +let array = [2, 1, 5, 6, 2, 3]; +console.log(maxArea(array)); + diff --git a/Queues/maxForSubArray.js b/Queues/maxForSubArray.js new file mode 100644 index 00000000..f526e0e1 --- /dev/null +++ b/Queues/maxForSubArray.js @@ -0,0 +1,21 @@ +function a(arr, k) { + + let result = []; + for(let i = 0; i < arr.length - k + 1; i++) { + let j = i; + let p = i + k - 1; + let temp = 0; + while(j <= p) { + temp = Math.max(temp, arr[j]); + j++; + } + result.push(temp); + temp = 0; + } + return result; +} + +let arr = [1, 2, 3, 1, 0, -1, 4, 5, 2, 3, 6]; +let k = 3; + +console.log(a(arr, k)); \ No newline at end of file diff --git a/Queues/queue.js b/Queues/queue.js new file mode 100644 index 00000000..87569403 --- /dev/null +++ b/Queues/queue.js @@ -0,0 +1,46 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +const queue = new Queue(); + +queue.enqueue(10); +queue.enqueue(20); +queue.enqueue(30); +queue.enqueue(40); +queue.enqueue(50); + +queue.dequeue(); +queue.dequeue(); + +console.log(queue.isEmpty()); \ No newline at end of file diff --git a/Queues/queueUsingStack.js b/Queues/queueUsingStack.js new file mode 100644 index 00000000..4aa7e053 --- /dev/null +++ b/Queues/queueUsingStack.js @@ -0,0 +1,48 @@ +class Queue { + constructor() { + this.stack1 = []; + this.stack2 = []; + this.rear1 = 0; + this.front1 = 0; + this.rear2 = 0; + this.front2 = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length == 0; + } + + enqueue(element) { + this.stack1[this.rear++] = element; + } + + dequeue() { + while(this.front1 < this.rear1) { + this.stack2[this.rear2++] = this.stack1[this.front1++]; + } + let temp = this.stack1[this.front1++]; + return temp; + } + + getFront() { + if(!this.isEmpty()) { + return this.stack1[this.front]; + } + return undefined; + } +} + +const queue = new Queue(); + +queue.enqueue(10); +queue.enqueue(20); +queue.enqueue(30); +queue.enqueue(40); +queue.enqueue(50); +console.log(queue.dequeue()); + + +// console.log(queue.getFront()); \ No newline at end of file diff --git a/Queues/reverseQueue.js b/Queues/reverseQueue.js new file mode 100644 index 00000000..1fe4898b --- /dev/null +++ b/Queues/reverseQueue.js @@ -0,0 +1,60 @@ + +//! 10/02/2022 +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +function reverseQueue() { + let array = []; + while(queue.length() > 0) { + array.push(queue.dequeue()); + } + + for(let i = array.length - 1; i >= 0; i--) { + queue.enqueue(array[i]); + } +} + + +const queue = new Queue(); + +queue.enqueue(10); +queue.enqueue(20); +queue.enqueue(30); +queue.enqueue(40); +queue.enqueue(50); + +reverseQueue(); + +console.log(queue.getFront()); + + diff --git a/Queues/stackUsingQueue.js b/Queues/stackUsingQueue.js new file mode 100644 index 00000000..e1d8dd60 --- /dev/null +++ b/Queues/stackUsingQueue.js @@ -0,0 +1,69 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +class StackUsingQueue { + constructor() { + this.primary = new Queue(); + this.secondary = new Queue(); + + } + + push(key) { + this.primary.enqueue(key); + } + + pop() { + while(this.primary.length() > 1) { + this.secondary.enqueue(this.primary.dequeue()); + } + + let temp = this.primary.dequeue(); + + while(this.secondary.length() > 0) { + this.primary.enqueue(this.secondary.dequeue()); + } + return temp; + } + +} + + +const st = new StackUsingQueue(); + +st.push(10); +st.push(20); +st.push(30); +st.push(40); +st.push(50); + +console.log(st.pop()); \ No newline at end of file diff --git a/Recursion/NthFibonacci.js b/Recursion/NthFibonacci.js new file mode 100644 index 00000000..e1369d31 --- /dev/null +++ b/Recursion/NthFibonacci.js @@ -0,0 +1,33 @@ +//! https://www.algoexpert.io/questions/Nth%20Fibonacci +//! O(n) time | O(1) space + +function getNthFib(n) { + const lastTwo = [0, 1]; + let counter = 3; + while(counter <= n) { + const nextFib = lastTwo[0] + lastTwo[1]; + lastTwo[0] = lastTwo[1]; + lastTwo[1] = nextFib; + counter++; + } + return n > 1 ? lastTwo[1] : lastTwo[0]; +} + +//! O(n) time | O(n) space | DynamicProgramming + +function getNthFib(n, memoize = {1: 0, 2: 1}) { + if(n in memoize) { + return memoize[n]; + } else { + memoize[n] = getNthFib(n - 1, memoize) + getNthFib(n - 2, memoize); + return memoize[n]; + } +} + +//! O(2^n) time | O(n) space + +function getNthFib(n) { + if(n == 2) return 1; + if(n == 1) return 0; + else return getNthFib(n - 1) + getNthFib(n - 2); +} diff --git a/Recursion/dummy.cpp b/Recursion/dummy.cpp new file mode 100644 index 00000000..e69de29b diff --git a/Recursion/dummy.js b/Recursion/dummy.js new file mode 100644 index 00000000..059f8d8c --- /dev/null +++ b/Recursion/dummy.js @@ -0,0 +1,101 @@ +// function fun(array) { +// let counter = Infinity; +// for(let i = 0; i < array.length; i++) { +// let sum = 0; +// if(isPowerOf2(array[i])) { +// return 1; +// }else { +// let temp = 1; +// sum = sum + array[i]; +// for(var j = 0; j < array.length; j++) { +// if(i != j) { +// sum = sum + array[j]; +// if(isPowerOf2(sum)) { +// temp++; +// counter = Math.min(counter, temp); +// break; +// } else { +// sum = sum - array[j]; +// temp--; +// } +// } +// } +// } +// } +// return counter == Infinity? -1: counter; +// } + +// function isPowerOf2(n) { +// if(n == 1) return true; +// return parseInt( (Math.ceil((Math.log(n) / Math.log(2))))) == parseInt( (Math.floor(((Math.log(n) / Math.log(2)))))); +// } + +// const array = [1, 2, 3, 1]; + +// console.log(fun(array)); +// var numJewelsInStones = function(jewels, stones) { + +// const obj = {}; +// let counter = 0; + +// for(let i = 0; i < jewels.length; i++) { +// obj[jewels[i]] = true; +// } + +// for(let i = 0; i < stones.length; i++) { +// const temp = stones[i]; +// if(obj[temp]) { +// console.log(obj); +// counter++; +// } +// } +// return counter; +// }; + +// const jewels = "aA"; +// const stones = "aAAbbbb"; + + +// console.log(numJewelsInStones(jewels, stones)) + + + +function phoneNumberMnemonics(phoneNumber) { + if(!phoneNumber) return []; + const currentMnemonic = new Array(phoneNumber.length).fill('0'); + const mnemonicsFound = []; + phoneNumberMnemonicsHelper(0, currentMnemonic, phoneNumber, mnemonicsFound); + return mnemonicsFound; +} + +function phoneNumberMnemonicsHelper(idx, currentMnemonic, phoneNumber, mnemonicsFound) { + + if(idx == phoneNumber.length) { + currentMnemonic = currentMnemonic.join(''); + mnemonicsFound.push(currentMnemonic); + return; + } else { + const digit = phoneNumber[idx]; + const letters = DIGIT_LETTERS[digit]; + for(const letter of letters) { + currentMnemonic[idx] = letter; + phoneNumberMnemonicsHelper(idx + 1, currentMnemonic, phoneNumber, mnemonicsFound); + } + } +} + +const DIGIT_LETTERS = { + 1: ['1'], + 2: ['a', 'b', 'c'], + 3: ['d', 'e', 'f'], + 4: ['g', 'h', 'i'], + 5: ['j', 'k', 'l'], + 6: ['m', 'n', 'o'], + 7: ['p', 'q', 'r', 's'], + 8: ['t', 'u', 'v'], + 9: ['w', 'x', 'y', 'z'], + 0: ['0'] +} + + +console.log(phoneNumberMnemonics('2')); \ No newline at end of file diff --git a/Recursion/palindrome.js b/Recursion/palindrome.js new file mode 100644 index 00000000..27438c41 --- /dev/null +++ b/Recursion/palindrome.js @@ -0,0 +1,10 @@ +function palindrome(i, n, str) { + if(i >= n / 2) return true; + + if(str[i] !== str[n - i - 1]) return false; + + return palindrome(i + 1, n, str); +} + +const str = 'maadam'; +console.log(palindrome(0, str.length, str)); \ No newline at end of file diff --git a/Recursion/permutations.js b/Recursion/permutations.js new file mode 100644 index 00000000..6d9325c1 --- /dev/null +++ b/Recursion/permutations.js @@ -0,0 +1,49 @@ +//! https://www.algoexpert.io/questions/Permutations + +//! Upper Bound: O(n^2*n!) time | O(n*n!) space +//! Roughly: O(n*n!) time | O(n*n!) space + +function getPermutations(array) { + const permutations = []; + permutationsHelper(array, [], permutations); + return permutations; +} + +function permutationsHelper(array, currentPermutation, permutations) { + if(!array.length && currentPermutation) { + permutations.push(currentPermutation); + } else { + for(let i = 0; i < array.length; i++) { + const newArray = array.slice(0, i).concat(array.slice(i + 1)); + const newPermutation = currentPermutation.concat(array[i]); + permutationsHelper(newArray, newPermutation, permutations); + } + } +} + +const array = [1, 2, 3]; + +console.log(getPermutations(array)); + +//! O(n*n!) time | O(n*n!) space +// function getPermutations(array) { +// const permutations = []; +// permutationsHelper(0, array, permutations); +// return permutations; +// } +// function permutationsHelper(i, array, permutations) { +// if(i == array.length - 1) { +// permutations.push(array.slice()); +// } else { +// for(let j = i; j < array.length; j++) { +// swap(i, j, array); +// permutationsHelper(i + 1, array, permutations); +// swap(i, j, array); +// } +// } +// } +// function swap(i, j, array) { +// const temp = array[i]; +// array[i] = array[j]; +// array[j] = temp; +// } \ No newline at end of file diff --git a/Recursion/phoneNumberMnemonics.js b/Recursion/phoneNumberMnemonics.js new file mode 100644 index 00000000..f4faa32f --- /dev/null +++ b/Recursion/phoneNumberMnemonics.js @@ -0,0 +1,38 @@ +//! https://www.algoexpert.io/questions/Phone%20Number%20Mnemonics + +function phoneNumberMnemonics(phoneNumber) { + const currentMnemonic = new Array(phoneNumber.length).fill('0'); + const mnemonicsFound = []; + + phoneNumberMnemonicsHelper(0, phoneNumber, currentMnemonic, mnemonicsFound); + return mnemonicsFound; +} +function phoneNumberMnemonicsHelper(idx, phoneNumber, currentMnemonic, mnemonicsFound) { + if(idx == phoneNumber.length) { + const mnemonic = currentMnemonic.join(''); //! O(n) time operation + mnemonicsFound.push(mnemonic); + } else { + const digit = phoneNumber[idx]; + const letters = DIGIT_LETTERS[digit]; + for(const letter of letters) { + currentMnemonic[idx] = letter; + // console.log(currentMnemonic); + phoneNumberMnemonicsHelper(idx + 1, phoneNumber, currentMnemonic, mnemonicsFound); + } + } +} + +const DIGIT_LETTERS = { + 0: ['0'], + 1: ['1'], + 2: ['a', 'b', 'c'], + 3: ['d', 'e' , 'f'], + 4: ['g', 'h', 'i'], + 5: ['j', 'k', 'l'], + 6: ['m', 'n', 'o'], + 7: ['p', 'q', 'r', 's'], + 8: ['t', 'u', 'v'], + 9: ['w', 'x', 'y', 'z'] +}; + +console.log(phoneNumberMnemonics('1905')); \ No newline at end of file diff --git a/Recursion/powerset.js b/Recursion/powerset.js new file mode 100644 index 00000000..c50a5412 --- /dev/null +++ b/Recursion/powerset.js @@ -0,0 +1,27 @@ +//! O(n*2^n) time | O(n*2^n) space +function powerset(array, idx = null) { + if(idx == null) idx = array.length - 1; + if(idx < 0) return [[]]; + const ele = array[idx]; + const subsets = powerset(array, idx - 1); + const length = subsets.length; + for(let i = 0; i < length; i++) { + const currentSubset = subsets[i]; + subsets.push(currentSubset.concat(ele)); + } + return subsets; +} +console.log(powerset([1, 2, 3])); + +//! O(n*2^n) time | O(n*2^n) space +function powerset(array) { + const subsets = [[]]; + for(const ele of array) { + const length = subsets.length; + for(let i = 0; i < length; i++) { + const currentSubset = subsets[i]; + subsets.push(currentSubset.concat(ele)); + } + } + return subsets; +} \ No newline at end of file diff --git a/Recursion/productSum.js b/Recursion/productSum.js new file mode 100644 index 00000000..176b0622 --- /dev/null +++ b/Recursion/productSum.js @@ -0,0 +1,4 @@ +function productSum(array, multipler = 1, len = array.length) { + if(len = array.length) return multipler; + +} \ No newline at end of file diff --git a/Recursion/ratInMate.js b/Recursion/ratInMate.js new file mode 100644 index 00000000..63c5ee10 --- /dev/null +++ b/Recursion/ratInMate.js @@ -0,0 +1,48 @@ +function findPathHelper(i, j, arr, n, ans, mov, visited) { +if(i == n - 1 && j == n - 1) { + ans.push(mov); + return; +} + +// downward + if(i + 1 < n && !visited[i + 1][j] && arr[i + 1][j] === 1) { + visited[i][j] = 1; + findPathHelper(i + 1, j, arr, n, ans, mov + "D", visited); + visited[i][j] = 0; + } + // left + if(j - 1 > -1 && !visited[i][j - 1] && arr[i][j - 1] === 1) { + visited[i][j] = 1; + findPathHelper(i, j - 1, arr, n, ans, mov + "L", visited); + visited[i][j] = 0; + } + // right + if(j + 1 < n && !visited[i][j + 1] && arr[i][j + 1] === 1) { + visited[i][j] = 1; + findPathHelper(i, j + 1, arr, n, ans, mov + "R", visited); + visited[i][j] = 0; + } + // upward + if(i - 1 > -1 && !visited[i - 1][j] && arr[i - 1][j] === 1) { + visited[i][j] = 1; + findPathHelper(i - 1, j, arr, n, ans, mov + "U", visited); + visited[i][j] = 0; + } +} + +function findPath(m, n) { + var ans = []; + var visited = [...Array(n)].map(e => Array(n)); + if (m[0][0] === 1) findPathHelper(0, 0, m, n, ans, "", visited); + return ans; +} + +const m = [ [1, 0, 0, 0], + [1, 1, 0, 1], + [1, 1, 0, 0], + [0, 1, 1, 1] +]; +const n = 4; +console.log(findPath(m, n)); + + diff --git a/Recursion/stairCase.js b/Recursion/stairCase.js new file mode 100644 index 00000000..d3fa9b3f --- /dev/null +++ b/Recursion/stairCase.js @@ -0,0 +1,70 @@ +//! https://www.algoexpert.io/questions/Staircase%20Traversal + +//? using sliding window O(n) time | O(n) space + +function stairCaseTraversal(height, maxSteps) { + let currentNumberOfWays = 0; + const waysToTop = [1]; + + for(currentHeight = 1; currentHeight < height + 1; currentHeight++) { + const startOfWindow = currentHeight - maxSteps - 1; + const endOfWindow = currentHeight - 1; + if(startOfWindow >= 0) currentNumberOfWays -= waysToTop[startOfWindow]; + currentNumberOfWays += waysToTop[endOfWindow] + waysToTop.push(currentNumberOfWays); + } + return waysToTop[height]; +} + +//? O(n * k) time | O(n) space +function stairCaseTraversal(height, maxSteps) { + const waysToTop = new Array(height + 1).fill(0); + waysToTop[0] = 1; + waysToTop[1] = 1; + + for(let currentHeight = 2; currentHeight < height + 1; currentHeight++) { + let step = 1; + while(step <= maxSteps && step <= currentHeight) { + waysToTop[currentHeight] = waysToTop[currentHeight] + waysToTop[currentHeight - 1]; + step++; + } + } + return waysToTop[height]; +} + +//! O(n*k) time | O(n) space - where n is the height of the staircase and k is the number of allowed steps. +//todo using Dynamic Programming + +function stairCaseTraversal(height, maxSteps) { + return numberOfWaysToTop(height, maxSteps, {0: 1, 1: 1}); +} + +function numberOfWaysToTop(height, maxSteps, memoize) { + if(height in memoize) { + return memoize[height]; + } + let numberOfWays = 0; + for(let step = 1; step < Math.min(height, maxSteps) + 1; step++) { + numberOfWays += numberOfWaysToTop(height - step, maxSteps, memoize) + } + memoize[height] = numberOfWays; + + return numberOfWays; +} + +//! O(k^n) time | O(n) space - where n is the height of the staircase and k is the number of allowed steps. +function stairCaseTraversal(height, maxSteps) { + return numberOfWaysToTop(height, maxSteps); +} + +function numberOfWaysToTop(height, maxSteps) { + if(height <= 1) return 1; + + let numberOfWays = 0; + for(let step = 1; step < Math.min(height, maxSteps) + 1; step++) { + numberOfWays += numberOfWaysToTop(height - step, maxSteps); + } + return numberOfWays; +} + +console.log(stairCaseTraversal(4, 2)); \ No newline at end of file diff --git a/Recursion/subsequence.js b/Recursion/subsequence.js new file mode 100644 index 00000000..96dac55c --- /dev/null +++ b/Recursion/subsequence.js @@ -0,0 +1,47 @@ +// O(2**N * N) time | O(N) space + +function subsequence(i, n, array, sequence) { + if (i === n) { + if (sequence.length == 0) { + console.log("{}"); + } else console.log(sequence); + return; + } + + //take or pick the particular index into the subsequence. + sequence.push(array[i]); + subsequence(i + 1, n, array, sequence); + sequence.pop(); + + //Do not take or do not pick the particular index into the subsequence. + subsequence(i + 1, n, array, sequence); +} + +const array = [3, 1, 2]; + +// subsequence(0, array.length, array, []); + + +//! Reverse order + +function subsequenceReverse(i, n, array, sequence) { + if (i === n) { + if (sequence.length == 0) { + console.log("{}"); + } else console.log(sequence); + return; + } + + //Do not take or do not pick the particular index into the subsequence. + subsequenceReverse(i + 1, n, array, sequence); + + //take or pick the particular index into the subsequence. + sequence.push(array[i]); + subsequenceReverse(i + 1, n, array, sequence); + sequence.pop(); +} + + + + +subsequenceReverse(0, array.length, array, []); \ No newline at end of file diff --git a/Recursion/subsequenceSum.js b/Recursion/subsequenceSum.js new file mode 100644 index 00000000..983ec8fd --- /dev/null +++ b/Recursion/subsequenceSum.js @@ -0,0 +1,22 @@ +function subsequenceSum(i, nums, currentSum, array, sum) { + + if(i == n) { + if(currentSum == sum) { + console.log(nums); + } + return; + } + nums.push(array[i]); + currentSum += array[i]; + subsequenceSum(i + 1, nums, currentSum, array, sum); + + currentSum -= array[i]; + nums.pop(); + subsequenceSum(i + 1, nums, currentSum, array, sum); +} + +const array = [1, 2, 1]; +const n = array.length; +const sum = 2; + +subsequenceSum(0, [], 0, array, sum); diff --git a/Recursion/sudoku.js b/Recursion/sudoku.js new file mode 100644 index 00000000..6c8e29bd --- /dev/null +++ b/Recursion/sudoku.js @@ -0,0 +1,80 @@ +function solveSudoku(board) { + solvePartialSudoku(0, 0, board); + return board; +} + +function solvePartialSudoku(row, col, board) { + let currentRow = row; + let currentCol = col; + + if(currentCol == board[currentRow].length) { + currentRow++; + currentCol = 0; + + if(currentRow == board.length) return true; + } + + if(board[currentRow][currentCol ] == 0) { + return tryDigitsAtPosition(currentRow, currentCol, board); + } + return solvePartialSudoku(currentRow, currentCol + 1, board); +} + +function tryDigitsAtPosition(row, col, board) { + for(let digit = 1; digit < 10; digit++) { + if(isValidAtPosition(digit, row, col, board)) { + board[row][col] = digit; + if(solvePartialSudoku(row, col + 1, board)) return true; + } + } + board[row][col] = 0; + return false; +} + +function isValidAtPosition(value, row, col, board) { + const rowIsValid = !board[row].includes(value); + const colIsValid = !board.map(r => r[col]).includes(value); + + if(!rowIsValid || !colIsValid) return false; + + //! check subgrid + const subgridRowStart = Math.floor(row / 3) * 3; + const subgridColStart = Math.floor(col / 3) * 3; + for(let rowIdx = 0; rowIdx < 3; rowIdx++) { + for(let colIdx = 0; colIdx < 3; colIdx++) { + const rowToCheck = subgridRowStart + rowIdx; + const colToCheck = subgridColStart + colIdx; + const existingValue = board[rowToCheck][colToCheck]; + + if(existingValue == value) return false; + } + } + return true; +} + +let board = [ + [7, 8, 0, 4, 0, 0, 1, 2, 0], + [6, 0, 0, 0, 7, 5, 0, 0, 9], + [0, 0, 0, 6, 0, 1, 0, 7, 8], + [0, 0, 7, 0, 4, 0, 2, 6, 0], + [0, 0, 1, 0, 5, 0, 9, 3, 0], + [9, 0, 4, 0, 6, 0, 0, 0, 5], + [0, 7, 0, 3, 0, 0, 0, 1, 2], + [1, 2, 0, 0, 0, 7, 4, 0, 0], + [0, 4, 9, 2, 0, 6, 0, 0, 7] +]; + +solveSudoku(board); + +display(board); + +function display(board) { + let result = "" + for(let i = 0; i < 9; i++) { + for(let j = 0; j < 9; j++) { + result += board[i][j] + " | "; + } + result += "\n"; + } + console.log(result); +} diff --git a/Recursion/swapNumbers.js b/Recursion/swapNumbers.js new file mode 100644 index 00000000..c7deacaf --- /dev/null +++ b/Recursion/swapNumbers.js @@ -0,0 +1,13 @@ +function swapNumbers(i, n, array) { + if(i >= n / 2) return; + swap(i, n - i - 1, array); + swapNumbers(i + 1, n, array); +} + +function swap(a, b, array) { + [ array[a], array[b]] = [ array[b], array[a]]; +} + +const array = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]; +swapNumbers(0, array.length, array); +console.log(array); \ No newline at end of file diff --git a/Searching/.DS_Store b/Searching/.DS_Store new file mode 100644 index 00000000..65dfc670 Binary files /dev/null and b/Searching/.DS_Store differ diff --git a/Searching/aggresive_cows.js b/Searching/aggresive_cows.js new file mode 100644 index 00000000..afede737 --- /dev/null +++ b/Searching/aggresive_cows.js @@ -0,0 +1,30 @@ +function can_we_put_c_cows_with_min_dist_d(d, cows, stalls) { + let last_placed_cow_pos = stalls[0]; + let no_of_cows_placed = 1; + for(let i = 1; i < stalls.length; i++) { + let dist = stalls[i] - last_placed_cow_pos; + if(dist >= d) { + no_of_cows_placed++; + last_placed_cow_pos = stalls[i]; + } + if(no_of_cows_placed == cows) { + return true; + } + } + return false; +} +function place_cows(cows, stalls) { + stalls.sort( (a, b) => a - b ); + let l = 1, r = stalls[stalls.length - 1] - stalls[0]; + let ans = 1; + while(l <= r) { + let mid = l + Math.floor( (r - l) / 2); + if(can_we_put_c_cows_with_min_dist_d(mid, cows, stalls)) { + ans = mid; + l = mid + 1; + } else r = mid - 1; + } + return ans; +} + +console.log(place_cows(3, [1, 2, 8, 4, 9])); \ No newline at end of file diff --git a/Searching/allocate_min_no_of_pages.js b/Searching/allocate_min_no_of_pages.js new file mode 100644 index 00000000..db514597 --- /dev/null +++ b/Searching/allocate_min_no_of_pages.js @@ -0,0 +1,34 @@ +//! Time O(logn * n) | space O(1) +function isAllocationPossible(array, students, m) { + let allocated_students = 1; + let pages = 0; + for(let i = 0; i < array.length; i++) { + if(array[i] > m) return false; + if(pages + array[i] > m) { + allocated_students++; + pages += array[i]; + } else { + pages += array[i]; + } + } + if(allocated_students > students) { + return false; + } return true; +} +function allocate_min_no_of_pages(books, students) { + if(books < students) return -1; + let ans = 0; + let low = Math.min(...books); //! min in array + let high = books.reduce( (a, b) => a + b); // ! sum of array elements + while(low <= high) { + let mid = Math.floor((low + high) / 2); + if(isAllocationPossible(books, students, mid)) { + ans = mid; + high = mid - 1; + } else low = mid + 1; + } + return ans; +} +let array = [12, 34, 67, 90]; +let students = 2; +console.log(allocate_min_no_of_pages(array, students)); diff --git a/Searching/binarySearch.js b/Searching/binarySearch.js new file mode 100644 index 00000000..9c54e4d2 --- /dev/null +++ b/Searching/binarySearch.js @@ -0,0 +1,37 @@ + +function binarySearch(array, target) { + return binarySearchHelper(array, target, 0, array.length - 1); +} + +//! O(nlogn) time | O(1) space +function binarySearchHelper(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + if(target == potentialMatch) { + return middle; + } else if(target < potentialMatch) { + right = middle - 1; + } else { + left = middle + 1; + } + } + return -1; +} + +//! O(nlogn) time | O(logn) space +function binarySearchHelper(array, target, left, right) { + + if(left > right) return -1; + + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + if(target == potentialMatch) { + return middle; + } else if(target < potentialMatch) { + return binarySearchHelper(array, target, left, middle - 1); + } else { + return binarySearchHelper(array, target, middle + 1, right); + } +} \ No newline at end of file diff --git a/Searching/findThreeLargestNumbers.js b/Searching/findThreeLargestNumbers.js new file mode 100644 index 00000000..1ad7b7c5 --- /dev/null +++ b/Searching/findThreeLargestNumbers.js @@ -0,0 +1,70 @@ +//! O(n) time | O(1) space +function findThreeLargestNumbers(array) { + const threeLargest = [null, null, null]; + for(const num of array) { + updateLargest(threeLargest, num); + } + return threeLargest; +} + +function updateLargest(threeLargest, num) { + if (threeLargest[2] == null | num > threeLargest[2]) { + shiftAndUpdate(threeLargest, num, 2); + } else if(threeLargest[1] == null || num > threeLargest[1]) { + shiftAndUpdate(threeLargest, num, 1); + } else if(threeLargest[0] == null || num > threeLargest[0]) { + shiftAndUpdate(threeLargest, num, 0); + } +} + +function shiftAndUpdate(array, num, idx) { + for(let i = 0; i <= idx; i++) { + if(i == idx) { + array[idx] = num; + } else { + array[i] = array[i + 1]; + } + } +} + + +//! O(n) time | O(1) space +function findThreeLargestNumbers(array) { + let firstLargest = -Infinity; + let firstLargestIdx; + let secondLargest = -Infinity; + let secondLargestIdx; + let thirdLargest = -Infinity; + let thirdLargestIdx; + for (let i = 0; i < array.length; i++) { + if (array[i] > firstLargest) { + firstLargestIdx = i; + firstLargest = array[i]; + } + } + swap(firstLargestIdx, 0, array); + for (let i = 1; i < array.length; i++) { + if (array[i] > secondLargest) { + secondLargestIdx = i; + secondLargest = array[i]; + } + } + swap(secondLargestIdx, 1, array); + for (let i = 2; i < array.length; i++) { + if (array[i] > thirdLargest) { + thirdLargestIdx = i; + thirdLargest = array[i]; + } + } + swap(thirdLargestIdx, 2, array); + + swap(0, 2, array); + return [array[0], array[1], array[2]] + +} + +function swap(a, b, array) { + let temp = array[a]; + array[a] = array[b]; + array[b] = temp; +} diff --git a/Searching/indexEqualsValue.js b/Searching/indexEqualsValue.js new file mode 100644 index 00000000..e273fe7e --- /dev/null +++ b/Searching/indexEqualsValue.js @@ -0,0 +1,48 @@ +function indexEqualsValue(array) { + return indexEqualsValueHelper(array, 0, array.length - 1); +} + +//! O(n) time | O(1) space +function indexEqualsValueHelper(array, leftIndex, rightIndex) { + while(leftIndex <= rightIndex) { + const middleIndex = rightIndex + Math.floor( (rightIndex - leftIndex) / 2 ); + const middleValue = array[middleIndex]; + if(middleValue < middleIndex) { + leftIndex = middleIndex + 1; + } else if(middleValue == middleIndex && middleIndex == 0) { + return middleIndex; + } else if(middleValue == middleIndex && array[middleIndex - 1] < middleValue - 1) { + return middleIndex; + } else { + rightIndex = middleIndex - 1; + } + } + return -1; +} +//! O(logn) time | O(logn) space +function indexEqualsValueHelper(array, leftIndex, rightIndex) { + if(leftIndex > rightIndex) return -1; + + const middleIndex = rightIndex + Math.floor( (rightIndex - leftIndex) / 2 ); + const middleValue = array[middleIndex]; + + if(middleValue < middleIndex) { + return indexEqualsValueHelper(array, middleIndex + 1, rightIndex); + } else if(middleValue == middleIndex && middleIndex == 0) { + return middleIndex; + } else if(middleValue == middleIndex && array[middleIndex - 1] < middleValue - 1) { + return middleIndex; + } else { + return indexEqualsValueHelper(array, leftIndex, middleIndex - 1); + } +} + +//! O(n) time | O(1) space +function indexEqualsValue(array) { + + for(let i = 0; i < array.length; i++) { + const value = array[i]; + if(i == value) return i; + } + return -1; +} \ No newline at end of file diff --git a/Searching/knuth_morris_pratt.js b/Searching/knuth_morris_pratt.js new file mode 100644 index 00000000..51518b8b --- /dev/null +++ b/Searching/knuth_morris_pratt.js @@ -0,0 +1,40 @@ +//! O(m + n) + +function longest_prefix_suffix(str) { + let lps = []; + lps[0] = 0; + let len = 0; + for(let i = 1; i < str.length;) { + if(str[len] === str[i]) { + len += 1; + lps[i] = len; + i+=1; + } else { + if(len == 0) { + lps[i] = 0; + i += 1; + } else { + len = lps[len-1]; + } + } + } + return lps; +} +function knuth_morris_pratt(str, pattern) { + let n = str.length; + let m = pattern.length; + let i = 0, j = 0; + let lps = longest_prefix_suffix(pattern); + while(i < n && j < m) { + if(str[i] == pattern[j]) { + i++; + j++; + } else { + if(j == 0) i++; + else j = lps[j - 1]; + } + } + if(j == m) return true; + return false; +} +console.log(knuth_morris_pratt("aefoaefcdaefcdaed", "aefcdaed")); \ No newline at end of file diff --git a/Searching/linearSearch.js b/Searching/linearSearch.js new file mode 100644 index 00000000..30c2ed87 --- /dev/null +++ b/Searching/linearSearch.js @@ -0,0 +1,8 @@ +function linearSearch(array, target) { + for(let i = 0; i < array.length; i++) { + if(arr[i] === target) return i; + } + return NaN; +} + + diff --git a/Searching/longest_palindrome_prefix.js b/Searching/longest_palindrome_prefix.js new file mode 100644 index 00000000..69346e61 --- /dev/null +++ b/Searching/longest_palindrome_prefix.js @@ -0,0 +1,23 @@ +function longest_palindrome_prefix(str) { + str = str + "$" + str.split("").reverse().join(""); + console.log(str); + let lps = []; + lps[0] = 0; + let len = 0; + for(let i = 1; i < str.length;) { + if(str[len] === str[i]) { + len += 1; + lps[i] = len; + i+=1; + } else { + if(len == 0) { + lps[i] = 0; + i += 1; + } else { + len = lps[len-1]; + } + } + } + return Math.max(...lps); +} +console.log(longest_palindrome_prefix("aabbc")); \ No newline at end of file diff --git a/Searching/longest_proper_prefix.js b/Searching/longest_proper_prefix.js new file mode 100644 index 00000000..9f89dff7 --- /dev/null +++ b/Searching/longest_proper_prefix.js @@ -0,0 +1,21 @@ +function longest_prefix_suffix(str) { + let lps = []; + lps[0] = 0; + let len = 0; + for(let i = 1; i < str.length;) { + if(str[len] === str[i]) { + len += 1; + lps[i] = len; + i+=1; + } else { + if(len == 0) { + lps[i] = 0; + i += 1; + } else { + len = lps[len-1]; + } + } + } + return lps; +} +console.log(longest_prefix_suffix("abcabcabc")); \ No newline at end of file diff --git a/Searching/lowerBound.js b/Searching/lowerBound.js new file mode 100644 index 00000000..9537f3b6 --- /dev/null +++ b/Searching/lowerBound.js @@ -0,0 +1,22 @@ +//! Given a sorted Array and a element x, find the first element +//! element in the array that less than x. + +function lowerBound(array, target) { + let l = 0; + let r = array.length - 1; + let ans = -1; + while(l <= r) { + let mid = Math.floor( (l + r) / 2); + if(array[mid] >= target) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + if(ans == -1) return NaN; //! if every element < target + return ans; +} + +let array = [1, 2, 2, 3, 3, 4, 6, 7]; +let target = 6; + + diff --git a/Searching/minCharForPalindrome.js b/Searching/minCharForPalindrome.js new file mode 100644 index 00000000..feb8be3b --- /dev/null +++ b/Searching/minCharForPalindrome.js @@ -0,0 +1,22 @@ +//!25/02/2022 + +function minChForPalindrome(s) { + let n = s.length; + let p = 31; + let m = 1000000007; + let h1 = 0; + let h2 = 0; + let pow = 1; + let ans = -1; + for(let i = 0; i < n; i++, pow = pow*p%m) { + h1 = (h1*p + s.charCodeAt(i))%m; + // console.log(h1); + h2 = (h2 + (s.charCodeAt(i))*pow)%m; + // console.log(h2); + if(h1 == h2) ans = i; + } + return n - ans - 1; +} + +console.log(minChForPalindrome("abac")); + diff --git a/Searching/no_of_rectangles.js b/Searching/no_of_rectangles.js new file mode 100644 index 00000000..cbe49a92 --- /dev/null +++ b/Searching/no_of_rectangles.js @@ -0,0 +1,18 @@ +function can_we_fit_n_rect_in_sq_of_m(n, w, h, m) { + return (Math.floor(m / w) * Math.floor(m / h)) >= n; +} + +function min_rect(n, w, h) { + let l = 1, r = Math.max(w, h)*n; + let ans = 0; + while(l <= r) { + let mid = l + Math.floor( (r - l) / 2); + if(can_we_fit_n_rect_in_sq_of_m(n, w, h, mid)) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + return ans; +} + +console.log(min_rect(10, 2, 3)); \ No newline at end of file diff --git a/Searching/notATriangle.js b/Searching/notATriangle.js new file mode 100644 index 00000000..d4e41450 --- /dev/null +++ b/Searching/notATriangle.js @@ -0,0 +1,27 @@ + function upper_bound(array, target) { + let left = 0; + let right = array.length - 1; + let ans = -1; + while(left <= right) { + let mid = Math.floor( (left + right) / 2); + if(array[mid] > target) { + ans = mid; + right = mid - 1; + } else left = mid + 1; + } + if (ans == -1) return array.length; + return ans; +} +function triangle(array) { + array.sort( (a, b) => a - b); + let len = array.length; + let ans = 0; + for(let i = 0; i < len; i++) { + for(let j = i + 1; j < len - 1; j++) { + const sum = array[i] + array[j]; + ans += len - upper_bound(array, sum); + } + } + return ans; +} +console.log(triangle([4, 2, 10])); \ No newline at end of file diff --git a/Searching/printing_copies.js b/Searching/printing_copies.js new file mode 100644 index 00000000..a64dd73e --- /dev/null +++ b/Searching/printing_copies.js @@ -0,0 +1,20 @@ +function can_i_make_copies_in_m_seconds(m, x, y, d) { +// m --> is the time, d --> requires number of copies, x & y are the speed of machines +return (Math.floor(m / x) + Math.floor(m / y) >= d); +} + +function min_time_for_n_copies(x, y, n) { + if(n == 1) return Math.min(x, y, n); + let l = 0, r = Math.max(x, y) * n; + let ans = 0; + while(l <= r) { + let mid = l + Math.floor( (r - l) / 2); + if(can_i_make_copies_in_m_seconds(mid, x, y, n - 1)) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + return ans + Math.min(x, y); +} + +console.log(min_time_for_n_copies(1, 2, 5)); \ No newline at end of file diff --git a/Searching/quickSelect.js b/Searching/quickSelect.js new file mode 100644 index 00000000..9d5d1e3b --- /dev/null +++ b/Searching/quickSelect.js @@ -0,0 +1,45 @@ +//! https://leetcode.com/problems/kth-largest-element-in-an-array/ + +//! aka kth-largest-element-in-an-array + +//! Best: O(n) time | O(1) space +//! Average: O(n) time | O(1) space +//! Worst: O(n^2) time | O(1) space + +function quickSelect(array, k) { + const position = k - 1; + return quickSelectHelper(array, 0, array.length - 1, position); +} + +function quickSelectHelper(array, startIdx, endIdx, position) { + + while (true) { + if (startIdx > endIdx) { + throw new Error('Algorithm should never arrive here!'); + } + let i = startIdx; + let pivot = array[i]; + for (let j = i + 1; j <= endIdx; j++) { + if (array[j] < pivot) { + i++; + swap(i, j, array); + } + } + swap(startIdx, i, array); + if (i == position) { + return array[position]; + } else if (i < position) { + startIdx = i + 1; + } else { + endIdx = i - 1; + } + } +} +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +const array = [8, 5, 2, 9, 7, 6, 3]; +const k = 3 + +console.log(quickSelect(array, k)); \ No newline at end of file diff --git a/Searching/rabin_karp.js b/Searching/rabin_karp.js new file mode 100644 index 00000000..f6e37e1e --- /dev/null +++ b/Searching/rabin_karp.js @@ -0,0 +1,36 @@ +//!25/02/2022 +function rabin_karp(s, p) { + let prime = 31; + let m = 1000000007; //! 10^9 + 70 + let p_pow = [1]; + for(let i = 1; i < s.length; i++) { + p_pow[i] = (p_pow[i-1]*prime)%m; + } + // console.log(p_pow); + let p_h = [0]; + for(let i = 0; i < s.length; i++) { + p_h[i + 1] = (p_h[i] + (s.charCodeAt(i)*p_pow[i])%m) %m; + } + // console.log(p_h); + let hash_pat = 0; + for(let i = 0; i < p.length; i++) { + hash_pat = (hash_pat + (p.charCodeAt(i)*p_pow[i])%m)%m; + } + // console.log(hash_pat); + for(let i = 0; i <= s.length - p.length; i++) { + let curr_substring_hash = (p_h[i+p.length] - p_h[i] + m)%m; + if(curr_substring_hash == (hash_pat*p_pow[i])%m) { + //! manual match + console.log(curr_substring_hash); + let flag = true; + for(let j = 0; j < p.length; j++) { + if(s[i + j] != p[j]) { + flag = false; + break; + } + } + if(flag) console.log(i); + } + } +} +rabin_karp("aabbabcbbaabcab", "abc"); \ No newline at end of file diff --git a/Searching/searchForRange.js b/Searching/searchForRange.js new file mode 100644 index 00000000..4567670e --- /dev/null +++ b/Searching/searchForRange.js @@ -0,0 +1,115 @@ +//! https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ +//! FAANG + +function searchForRange(array, target) { + const finalRange = [-1, -1]; + alteredBinarySearch(array, target, 0, array.length - 1, finalRange, true); + alteredBinarySearch(array, target, 0, array.length - 1, finalRange, false); + return finalRange; +} + +//! O(logn) time | O(1) space +function alteredBinarySearch(array, target, left, right, finalRange, goLeft) { + + while(left <= right) { + + const mid = Math.floor( (left + right) / 2); + + if(target < array[mid]) { + right = mid - 1; + } else if(target > array[mid]) { + left = mid + 1; + } else { + if(goLeft) { + if(mid == 0 || array[mid - 1] != target) { + finalRange[0] = mid; + return; + } else { + right = mid -1; + } + } else { + if(mid == array.length - 1 || array[mid + 1] != target) { + finalRange[1] = mid; + return; + } else { + left = mid + 1; + } + } + } + } +} + +//! O(logn) time | O(logn) space +function alteredBinarySearch(array, target, left, right, finalRange, goLeft) { + if(left > right) return; + + const mid = Math.floor( (left + right) / 2); + + if(target < array[mid]) { + alteredBinarySearch(array, target, left, mid - 1, finalRange, goLeft); + } else if(target > array[mid]) { + alteredBinarySearch(array, target, mid + 1, right, finalRange, goLeft); + } else { + if(goLeft) { + if(mid == 0 || array[mid - 1] != target) { + finalRange[0] = mid; + return; + } else { + alteredBinarySearch(array, target, left, mid - 1, finalRange, goLeft); + } + } else { + if(mid == array.length - 1 || array[mid + 1] != target) { + finalRange[1] = mid; + return; + } else { + alteredBinarySearch(array, target, mid + 1, right, finalRange, goLeft); + } + } + } +} + + +function searchForRange(array, target) { + return searchForRangeHelper(array, target, 0, array.length - 1); +} + +function searchForRangeHelper(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor( (left + right) / 2); + const potentialMatch = array[middle]; + + if(target == potentialMatch) { + const startIdx = linearSearch(array, target, 0, middle); + const endIdx = findLastIdx(array, target, middle + 1, right); + return [startIdx, endIdx]; + } else if(target < potentialMatch) { + right = middle - 1; + } else if(target > potentialMatch) { + left = middle + 1; + } + } return [-1, -1]; +} + +function linearSearch(array, target, left, right) { + for(let i = 0; i <= right; i++) { + if(array[i] == target) { + return i; + } + } +} + +function findLastIdx(array, target, left, right) { + let idx; + for(let i = left; i <= right; i++) { + if(array[i] == target) { + idx = i; + } + } + return idx; +} + +let array = [0, 1, 21, 33, 45, 45, 45, 45, 45, 45, 61, 71, 73]; +const target = 45; + +console.log(searchForRange(array, target)); \ No newline at end of file diff --git a/Searching/searchInSortedMatrix.js b/Searching/searchInSortedMatrix.js new file mode 100644 index 00000000..35af94d7 --- /dev/null +++ b/Searching/searchInSortedMatrix.js @@ -0,0 +1,16 @@ +//! O(n + m) time | O(1) space + +function searchInSortedMatrix(matrix, target) { + let row = 0; + let col = matrix[0].length - 1; + + while(row < matrix.length && col >= 0) { + if(matrix[row][col] > target) { + col--; + } else if(matrix[row][col] < target) { + row++; + } else { + return [row, col]; + } + } return [-1, -1]; +} \ No newline at end of file diff --git a/Searching/sexTuples.js b/Searching/sexTuples.js new file mode 100644 index 00000000..5dbf7b1b --- /dev/null +++ b/Searching/sexTuples.js @@ -0,0 +1,60 @@ +function lower_bound(array, target) { + let left = 0; + let right = array.length - 1; + let ans = -1; + while(left <= right) { + let mid = Math.floor((left + right) / 2); + if(array[mid] >= target) { + ans = mid; + right = mid - 1; + } else left = mid + 1; + } + if(ans == -1) return NaN; + return ans; +} + function upper_bound(array, target) { + let left = 0; + let right = array.length - 1; + let ans = -1; + while(left <= right) { + let mid = Math.floor( (left + right) / 2); + if(array[mid] > target) { + ans = mid; + right = mid - 1; + } else left = mid + 1; + } + if (ans == -1) return NaN; + return ans; +} + + function sex_tuples(array) { + let len = array.length; + let lhs = []; + let rhs = []; + for(let i = 0; i < len; i++) { + for(let j = 0; j < len; j++) { + for(let k = 0; k < len; k++) { + lhs.push( array[i] * array[j] + array[k] ); + } + } + } + for(let i = 0; i < len; i++) { + if(array[i] == 0) continue; + for(let j = 0; j < len; j++) { + for(let k = 0; k < len; k++) { + rhs.push( array[i] * (array[j] + array[k]) ); + } + } + } + + rhs.sort( (a, b) => a - b); + let ans = 0; + for(let i = 0; i < lhs.length; i++) { + let lb = lower_bound(rhs, lhs[i]); + let ub = upper_bound(rhs, lhs[i]); + ans += (ub - lb); + } + return ans; +} +console.log(sex_tuples([2, 3])); + diff --git a/Searching/shiftedBinarySearch.js b/Searching/shiftedBinarySearch.js new file mode 100644 index 00000000..e231419f --- /dev/null +++ b/Searching/shiftedBinarySearch.js @@ -0,0 +1,93 @@ +function shiftedBinarySearch(array, target) { + return shiftedBinarySearchHelper(array, target, 0, array.length - 1); +} + +//! O(logn) time | O(1) space +function shiftedBinarySearchHelper(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + const leftNum = array[left]; + const rightNum = array[right]; + + if(target == potentialMatch) return middle; + else if(leftNum <= potentialMatch) { + if(target < potentialMatch && target >= leftNum) { + right = middle - 1; + } else { + left = middle + 1; + } + } else { + if(target > potentialMatch && target <= rightNum) { + left = middle + 1; + } else { + right = middle - 1; + } + } + } return -1; +} + +//! O(logn) time | O(logn) space +function shiftedBinarySearchHelper(array, target, left, right) { + if(left > right) return -1; + + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + const leftNum = array[left]; + const rightNum = array[right]; + + if(target == potentialMatch) return middle; + else if(leftNum <= potentialMatch) { + if(target < potentialMatch && target >= leftNum) { + return shiftedBinarySearchHelper(array, target, left, middle - 1); + } return shiftedBinarySearchHelper(array, target, middle + 1, right); + } else { + if(target > potentialMatch && target <= rightNum) { + return shiftedBinarySearchHelper(array, target, middle + 1, right); + } + return shiftedBinarySearchHelper(array, target, left, middle - 1); + } +} + +//! O(n) time | O(1) space + +function shiftedBinarySearch(array, target) { + + let idx; + for(let i = 0; i < array.length - 1; i++) { + if(array[i] > array[i + 1]) { + idx = i; + break; + } + } + let isFound = binarySearch(array, target, 0, idx); + + if(isFound != -1) { + return isFound; + } + return binarySearch(array, target, idx + 1, array.length - 1); + +} + +function binarySearch(array, target, left, right) { + + while(left <= right) { + const middle = Math.floor((left + right) / 2); + const potentialMatch = array[middle]; + console.log(potentialMatch); + if(target == potentialMatch) { + return middle; + } else if(target < potentialMatch) { + right = middle - 1; + } else if (target > potentialMatch) { + left = middle + 1; + } + } + return -1; +} + +let array = [45, 61, 72, 72, 73, 0, 1, 21, 33, 37]; +const target = 33; + +console.log(shiftedBinarySearch(array, target)); \ No newline at end of file diff --git a/Searching/sqrt.js b/Searching/sqrt.js new file mode 100644 index 00000000..1ad9f3c4 --- /dev/null +++ b/Searching/sqrt.js @@ -0,0 +1,19 @@ +function sqrt(target) { + if(target == 10 || target == 1) return target; + if(target < 0) return NaN; + let low = 1; + let high = target - 1; + while(low <= high) { + let mid = low + Math.floor( (high - low) / 2); + if(mid * mid == target) return mid; + if(mid * mid < target) { + //? it can be a possible answer otherwise a better ans can be to the right. + ans = mid; + low = mid + 1; + } else { + high = mid - 1; + } + } + return ans; +} +console.log(sqrt(50)); \ No newline at end of file diff --git a/Searching/string_matching.js b/Searching/string_matching.js new file mode 100644 index 00000000..51fe9668 --- /dev/null +++ b/Searching/string_matching.js @@ -0,0 +1,18 @@ +//! brute force or Naive approach +//! time O((m - n + 1)*n) --> O(m*n) | space O(1) +function string_matching_naive(s, p) { + let m = s.length; + let n = p.length; + for(let i = 0; i <= (m - n); i++) { + let flag = true; + for(let j = 0; j < n; j++) { + if(s[i + j] != p[j]) { + flag = false; + break; + } + } + if(flag) console.log(i); + } +} + +string_matching_naive("aabbabcbbaabcab", "abc"); \ No newline at end of file diff --git a/Searching/upperBound.js b/Searching/upperBound.js new file mode 100644 index 00000000..21d95e91 --- /dev/null +++ b/Searching/upperBound.js @@ -0,0 +1,23 @@ +//! Given a sorted Array and a element x, find the first element +//! element in the array that greater than x. + +function upperBound(array, target) { + let l = 0; + let r = array.length - 1; + let ans = -1; + while(l <= r) { + let mid = Math.floor( (l + r) / 2); + if(array[mid] > target) { + ans = mid; + r = mid - 1; + } else l = mid + 1; + } + if(ans == -1) return NaN; //! if every element < target + return ans; +} +let array = [1, 2, 2, 3, 3, 4, 6, 7]; +let target = 5; + +console.log(upperBound(array, target)); + + diff --git a/Stacks/balancedBrackets.js b/Stacks/balancedBrackets.js new file mode 100644 index 00000000..3c7432c3 --- /dev/null +++ b/Stacks/balancedBrackets.js @@ -0,0 +1,26 @@ +//! O(n) time | O(n) space +function balancedBrackets(string) { + + const openingBrackets = '([{'; + const closingBrackets = ')]}'; + const matchingBrackets = { ')': '(', ']': '[', '}': '{'}; + const stack = []; + + for(const char of string) { + if(openingBrackets.includes(char)) { + stack.push(char); + } else if(closingBrackets.includes(char)) { + if(stack.length == 0) return false; + if(stack[stack.length - 1] == matchingBrackets[char]) { + stack.pop(); + } else { + return false; + } + } + } + return stack.length == 0; +} + +const string = "([])(){}(())()()"; + +console.log(balancedBrackets(string)); \ No newline at end of file diff --git a/Stacks/insertAtBottom.js b/Stacks/insertAtBottom.js new file mode 100644 index 00000000..4b3457bb --- /dev/null +++ b/Stacks/insertAtBottom.js @@ -0,0 +1,79 @@ +//! 07/02/2022 + +class Stack { + constructor() { + this.top = 0; + this.data = []; + } + + push(element) { + this.data[this.top] = element; + this.top = this.top + 1; + } + + isEmpty() { + return this.top == 0; + } + pop() { + if(this.isEmpty()) { + console.log("stack is underflow"); + return undefined; + } + this.top = this.top - 1; + return this.data.pop(); + } + //! top value + peek() { + if (this.isEmpty()) { + return undefined; + } + return this.data[this.top - 1]; + } +} + +const st = new Stack(); +st.push(100); +st.push(200); +st.push(300); +st.push(400); +st.push(500); +st.push(600); +st.push(700); +st.push(800); + +/** + * ! 1. create an array and pop every element from stack and push into stack. + * + * ! 2. use bottom up approach. + */ + +function insertAtBottomIterative(stack, element) { + const secondary = new Stack(); + + while (!st.isEmpty()) { + secondary.push(st.pop()); + } + st.push(element); + + while (!secondary.isEmpty()) { + st.push(secondary.pop()); + } + +} + +function insertAtBottomRecursively(stack, element) { + if (st.isEmpty()) { + st.push(element); + return; + } + const topElement = stack.pop(); + insertAtBottomRecursively(st, element); + st.push(topElement); +} +// insertAtBottomIterative(st, 10); +insertAtBottomRecursively(st, 10); + +console.log(st.peek()); + +console.log(st); + diff --git a/Stacks/matchingBrackets.js b/Stacks/matchingBrackets.js new file mode 100644 index 00000000..72caef96 --- /dev/null +++ b/Stacks/matchingBrackets.js @@ -0,0 +1,24 @@ +//! 07/02/2022 +function matchingBrackets(string) { + const openingBrackets = '({['; + const closingBrackets = ')}]'; + const matchingBrackets = { ')': '(', '}': '{', ']': '[' }; + + let stack = []; + + for(char of string) { + if(openingBrackets.includes(char)) { + stack.push(char); + } else if(closingBrackets.includes(char)) { + if(stack.length === 0) return false; + else if(stack[stack.length - 1] === matchingBrackets[char]) + stack.pop(); + } + } + return stack.length === 0; + } + + let string = '(({}}[]()))'; + + + console.log(matchingBrackets(string)); \ No newline at end of file diff --git a/Stacks/minMaxStackConstruction.js b/Stacks/minMaxStackConstruction.js new file mode 100644 index 00000000..c17e149e --- /dev/null +++ b/Stacks/minMaxStackConstruction.js @@ -0,0 +1,36 @@ +class minMaxStack { + constructor() { + this.minMaxStack = []; + this.stack = []; + } + //! O(1) time | O(1) space + peek() { + return this.stack[this.stack.length - 1]; + } + //! O(1) time | O(1) space + pop() { + this.minMaxStack.pop(); + return this.stack.pop(); + } + //! O(1) time | O(1) space + push(number) { + const newMinMax = {min: number, max: number}; + + if(this.minMaxStack.length) { + const lastMinMax = this.minMaxStack[this.minMaxStack.length - 1]; + newMinMax.min = Math.min(lastMinMax.min, number); + newMinMax.min = Math.max(lastMinMax.max, number); + } + this.minMaxStack.push(newMinMax); + this.stack.push(number); + } + //! O(1) time | O(1) space + getMin() { + return this.minMaxStack[this.minMaxStack.length - 1].min; + } + //! O(1) time | O(1) space + getMax() { + return this.maxMaxStack[this.maxMaxStack.length - 1].max; + } + +} \ No newline at end of file diff --git a/Stacks/nextGreater.js b/Stacks/nextGreater.js new file mode 100644 index 00000000..240c8f9e --- /dev/null +++ b/Stacks/nextGreater.js @@ -0,0 +1,19 @@ +//! 08/02/2022 + +function nextGreater(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = 0; i < array.length; i++) { + while(stack.length > 0 && array[stack[stack.length - 1]] < array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result; +} + +let array = [2, 7, 3, 5, 4, 6, 8]; + +console.log(nextGreater(array)); \ No newline at end of file diff --git a/Stacks/nextGreaterElement.js b/Stacks/nextGreaterElement.js new file mode 100644 index 00000000..77af7228 --- /dev/null +++ b/Stacks/nextGreaterElement.js @@ -0,0 +1,48 @@ +//! O(n) time | O(n) space +function nextGreaterElement(array) { + const result = new Array(array.length).fill(-1); + const stack = []; + + for(let idx = 2 * array.length - 1; idx > -1; idx--) { + + const circularIdx = idx % array.length; + while(stack.length > 0) { + if(stack[stack.length - 1] <= array[circularIdx]) { + stack.pop(); + } else { + result[circularIdx] = stack[stack.length - 1]; + break; + } + } + stack.push(array[circularIdx]); + } + return result; +} + +// function nextGreaterElement(arr) { +// let n = arr.length; +// let array = Array(2 * n); +// let result = []; +// for(let i = 0; i < arr.length; i++) { +// result[i] = -1; +// } +// for(let i = 0; i < arr.length; i++) { +// array[i] = array[n + i] = arr[i]; +// } +// for(let i = 0; i < arr.length; i++) { +// let j = i + 1; +// while(j < arr.length + i + 1) { +// if(array[j] > array[i]) { +// result[i] = array[j]; +// break; +// } +// j++; +// } +// } +// return result; +// } + + +const array = [2, 5, -3, -4, 6, 7, 2]; + +console.log(nextGreaterElement(array)) \ No newline at end of file diff --git a/Stacks/nextMinMax.js b/Stacks/nextMinMax.js new file mode 100644 index 00000000..04219a65 --- /dev/null +++ b/Stacks/nextMinMax.js @@ -0,0 +1,49 @@ +class Stack { + constructor() { + this.minMaxStack = []; + this.stack = []; + } + + peek() { + return this.stack[stack.length - 1]; + } + + pop() { + this.minMaxStack.pop(); + return this.stack.pop(); + } + + push(number) { + const newMinMax = {min: number, max: number}; + + if(this.minMaxStack.length) { + const lastMinMax = this.minMaxStack[this.minMaxStack.length - 1]; + newMinMax.min = Math.min(lastMinMax.min, number); + newMinMax.max = Math.max(lastMinMax.max, number); + } + this.minMaxStack.push(newMinMax); + this.stack.push(number); + + } + + getMin() { + return this.minMaxStack[this.minMaxStack.length - 1].min; + } + + getMax() { + return this.minMaxStack[this.minMaxStack.length -1].max; + } +} + + +const stack = new Stack(); + +stack.push(5); +stack.push(2); +console.log(stack.getMin()); +console.log(stack.getMax()); +stack.push(7); + +console.log(stack.getMin()); +console.log(stack.getMax()); + diff --git a/Stacks/nextSmaller.js b/Stacks/nextSmaller.js new file mode 100644 index 00000000..820ffdd7 --- /dev/null +++ b/Stacks/nextSmaller.js @@ -0,0 +1,20 @@ +//! 08/02/2022 +function nextSmaller(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = 0; i < array.length; i++) { + + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result; +} + +let array = [2, 7, 3, 5, 4, 6, 1]; + + +console.log(nextSmaller(array)); \ No newline at end of file diff --git a/Stacks/prevGreater.js b/Stacks/prevGreater.js new file mode 100644 index 00000000..42fac664 --- /dev/null +++ b/Stacks/prevGreater.js @@ -0,0 +1,23 @@ +//! 08/02/2022 +//! prevGreater is opposite of next smaller, just reverse given array and result array +function prevGreater(array) { + array.reverse(); + let result = new Array(array.length).fill(-1); + // const stack = new Stack(); + const stack = []; + + for(let i = 0; i < array.length; i++) { + + while(stack.length > 0 && array[stack[stack.length - 1]] < array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result.reverse(); +} + +let array = [2, 7, 3, 5, 4, 6, 1]; + + +console.log(prevGreater(array)); \ No newline at end of file diff --git a/Stacks/prevSmaller.js b/Stacks/prevSmaller.js new file mode 100644 index 00000000..1ceed553 --- /dev/null +++ b/Stacks/prevSmaller.js @@ -0,0 +1,18 @@ +//! 08/02/2022 +function prevSmaller(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = array.length - 1; i >= 0; i--) { + while(stack.length > 0 && array[stack[stack.length - 1]] > array[i]) { + const top = stack.pop(); + result[top] = array[i]; + } + stack.push(i); + } + return result; +} + +let array = [2, 7, 3, 5, 4, 6, 1]; + +console.log(prevSmaller(array)); \ No newline at end of file diff --git a/Stacks/removeConsecutiveDuplicates.js.js b/Stacks/removeConsecutiveDuplicates.js.js new file mode 100644 index 00000000..9159df6e --- /dev/null +++ b/Stacks/removeConsecutiveDuplicates.js.js @@ -0,0 +1,49 @@ + +//! 07/02/2022 +class Stack { + constructor() { + this.top = -1; + this.data = []; + } + + push(element) { + this.top = this.top + 1; + this.data[this.top] = element; + } + isEmpty() { + return this.top == 0; + } + + removeConsecutiveDuplicates(arr) { + + for (let i = 0; i < arr.length; i++) { + if (this.data[this.top] !== arr[i]) + st.push(arr[i]); + } + +} + +} +let arr = [1, 2, 1, 1, 3, 3, 3, 3, 2, 1, 1]; + +const st = new Stack(); + +st.removeConsecutiveDuplicates(arr); + +function removeDuplicates(arr) { + + let prev = arr[0]; + let result = []; + result.push(prev); + + for (let i = 1; i < arr.length; i++) { + if (arr[i] !== prev) { + prev = arr[i]; + result.push(prev); + } + } + console.log(result); +} + +removeDuplicates(arr); + diff --git a/Stacks/reverseStack.js b/Stacks/reverseStack.js new file mode 100644 index 00000000..ba45afb7 --- /dev/null +++ b/Stacks/reverseStack.js @@ -0,0 +1,71 @@ +//! 07/02/2022 +class Stack { + constructor() { + this.top = 0; + this.data = []; + } + + push(element) { + this.data[this.top] = element; + this.top = this.top + 1; + } + + isEmpty() { + return this.top == 0; + } + + pop() { + if(this.isEmpty()) { + console.log("stack is underflow"); + return undefined; + } + this.top = this.top - 1; + return this.data.pop(); + } + //! top value + peek() { + if (this.isEmpty()) { + return undefined; + } + return this.data[this.top - 1]; + } +} + +/** + * ! 1. create an array and pop every element from stack and push into stack. + * + * ! 2. use bottom up approach. + */ + +function insertAtBottomRecursively(stack, element) { + if (st.isEmpty()) { + st.push(element); + return; + } + const topElement = stack.pop(); + insertAtBottomRecursively(st, element); + st.push(topElement); +} + +function reverseStack(st) { + if(st.isEmpty()) return; + const topElement = st.pop(); + reverseStack(st); + insertAtBottomRecursively(st, topElement); +} + + +const st = new Stack(); +st.push(100); +st.push(200); +st.push(300); +st.push(400); +st.push(500); +st.push(600); +st.push(700); +st.push(800); + +reverseStack(st); + +console.log(st); + diff --git a/Stacks/sortStack.js b/Stacks/sortStack.js new file mode 100644 index 00000000..db29ef35 --- /dev/null +++ b/Stacks/sortStack.js @@ -0,0 +1,26 @@ +//! O(n^2) time | O(n) space + +function sortStack(stack) { + if(stack.length == 0) return stack; + + const top = stack.pop(); + + sortStack(stack); + + insertInSortedOrder(stack, top); + return stack; +} + +function insertInSortedOrder(stack, top) { + + if(stack.length == 0 || stack[stack.length - 1] <= top) { + stack.push(top); + return; + } + + const top = stack.pop(); + + insertInSortedOrder(stack, top) + + stack.push(top); +} \ No newline at end of file diff --git a/Stacks/stack.js b/Stacks/stack.js new file mode 100644 index 00000000..576d77a0 --- /dev/null +++ b/Stacks/stack.js @@ -0,0 +1,45 @@ +//! 07/02/2022 +class Stack { + constructor() { + this.top = 0; + this.data = []; + } + + push(element) { + this.data[this.top] = element; + this.top = this.top + 1; + } + + isEmpty() { + return this.top == 0; + } + + pop() { + if(this.isEmpty()) { + console.log("stack is underflow"); + return undefined; + } + this.top = this.top - 1; + return this.data.pop(); + } + //! top value + peek() { + if (this.isEmpty()) { + return undefined; + } + return this.data[this.top - 1]; + } +} + +const st = new Stack(); +st.push(100); +st.push(200); +st.push(300); +st.push(400); +st.push(500); +st.push(600); + +console.log(st.peek()); +st.pop(); + +console.log(st.peek()); \ No newline at end of file diff --git a/Stacks/stockSpan.js b/Stacks/stockSpan.js new file mode 100644 index 00000000..6fa5cb45 --- /dev/null +++ b/Stacks/stockSpan.js @@ -0,0 +1,29 @@ +//! 10/02/2022 + +function prevGreater(array) { + let result = new Array(array.length).fill(-1); + const stack = []; + + for(let i = array.length - 1; i >= 0; i--) { + while(stack.length > 0 && array[stack[stack.length - 1]] < array[i]) { + const top = stack.pop(); + result[top] = i; + } + stack.push(i); + } + return result; +} + +function stockSpan(array) { + let result = []; + const prev = prevGreater(array); + for(let i = 0; i < array.length; i++) { + result[i] = i - prev[i]; + } + return result; +} + +let array = [31, 27, 14, 21, 30, 22]; + +console.log(stockSpan(array)); + diff --git a/Stacks/sunsetViews.js b/Stacks/sunsetViews.js new file mode 100644 index 00000000..9fbcd2e1 --- /dev/null +++ b/Stacks/sunsetViews.js @@ -0,0 +1,26 @@ +//! O(n) time | O(n) space + +function sunsetViews(buildings, direction) { + const buildingsWithSunsetViews = []; + + const startIdx = direction == 'WEST' ? 0: buildings.length - 1; + const step = direction == 'WEST' ? 1 : -1; + + let idx = startIdx; + let runningMaxHeight = 0; + while(idx > -1 && idx < buildings.length) { + const buildingHeight = buildings[idx]; + + if(buildingHeight > runningMaxHeight) { + buildingsWithSunsetViews.push(idx); + } + runningMaxHeight = Math.max(runningMaxHeight, buildingHeight); + + idx = idx + step; + } + + if(direction == 'EAST') buildingsWithSunsetViews.reverse(); + + return buildingsWithSunsetViews; + +} \ No newline at end of file diff --git a/Strings/.DS_Store b/Strings/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/Strings/.DS_Store differ diff --git a/Strings/ceaserCipherEncryptor.js b/Strings/ceaserCipherEncryptor.js new file mode 100644 index 00000000..2d5a239d --- /dev/null +++ b/Strings/ceaserCipherEncryptor.js @@ -0,0 +1,14 @@ +//! 0(n) time | O(n) space +function caesarCipherEncryptor(string, key) { + const newLetters = []; + const newKey = key % 26; + for(const letter of string) { + newLetters.push(getNewLetter(letter, newKey)); + } + return newLetters.join(''); +} + +function getNewLetter(letter, key) { + const newLetterCode = letter.charCodeAt() + key; + return newLetterCode <= 122 ? String.fromCharCode(newLetterCode) : String.fromCharCode(96 + (newLetterCode % 122)); +} \ No newline at end of file diff --git a/Strings/firstNonRepeatingCharacter.js b/Strings/firstNonRepeatingCharacter.js new file mode 100644 index 00000000..de78b0d7 --- /dev/null +++ b/Strings/firstNonRepeatingCharacter.js @@ -0,0 +1,46 @@ +//! O(n^2) time | O(1) space - where n is the length of the input string +function firstNonRepeatingCharacter(string) { + for(let i = 0; i < string.length; i++) { + let foundDuplicate = false; + for(let j = 0; j < string.length; j++) { + if(string[i] === string[j] && i !== j) foundDuplicate = true; + } + if(!foundDuplicate) return i; + } + return -1; +} + +//! O(n) time | O(1) space - where n is the length of the input string +//! The constant space is because the input string only has lowercase. +//! English-alphabet letters; thus our hash table will never have more than +//! 26 character frequencies. + +function firstNonRepeatingCharacter(string) { + const characterFrequencies = {}; + + for(const character of string) { + if( !(character in characterFrequencies)) characterFrequencies[character] = 0; + characterFrequencies[character]++; + } + +for(let i = 0; i < string.length; i++) { + const character = string[i]; + if(characterFrequencies[character] === 1) return i; +} +return -1; +} + +//! my logic +function firstNonRepeatingCharacter(string) { + let hash_table = {}; + for(const char of string) { + if ( !(char in hash_table)) hash_table[char] = 0; + + hash_table[char]++; + } + for( const [char, count] of Object.entries(hash_table)) { + if(count == 1) return string.indexOf(char); //! indexOf take O(n) time for finding index + } return -1; +} +const string = "abbccddcaff"; +console.log(firstNonRepeatingCharacter(string)); \ No newline at end of file diff --git a/Strings/generateDocument.js b/Strings/generateDocument.js new file mode 100644 index 00000000..893b01ec --- /dev/null +++ b/Strings/generateDocument.js @@ -0,0 +1,71 @@ +//! O(n + m) time | O(c) space - where n is the number of characters, m is +//! ths length of the document, and c is the number of unique characters in the characters string. +function generateDocument(characters, document) { + const characterCounts = {}; + for(const character of characters) { + if(! (character in characterCounts)) characterCounts[character] = 0; + + characterCounts[character]++; + } + for(const character of document) { + if( !(character in characterCounts) || characterCounts[character] === 0) return false; + characterCounts[character]--; + } + return true; +} + + +//! O(m * (n + m)) time | O(1) space - where n is the number +//! of characters and m is the length of the document + +function generateDocument(characters, document) { +for(const character of document) { + const documentFrequency = countCharacterFrequency(character, document); + const charactersFrequency = countCharacterFrequency(character, characters); + if(documentFrequency > charactersFrequency) return false; +} + return true; +} + +function countCharacterFrequency(character, target) { + let frequency = 0; + for(const char of target) + if(char === character) frequency++; + return frequency; +} + + + +//! my logic, passed all test cases; +//! my logic O(n + m) time | O(c) space c is no of unique characters; +function generateDocument(characters, document) { + let hash_table = {}; + for(let i = 0; i < characters.length; i++) { + if(hash_table[characters[i]]) { + hash_table[characters[i]] += 1; + } else { + hash_table[characters[i]] = 1; + } + } + console.log(hash_table); + for(let i = 0; i < document.length; i++) { + if(!(document[i] in hash_table)) return false; + if(hash_table[document[i]] === 0) + return false; + hash_table[document[i]] -= 1; +} +console.log("------------------------"); +console.log(hash_table); + return true; +} + +let characters = "Bste!hetsi ogEAxpelrt x "; +let document = "AlgoExpert is the Best!"; + +let characters = "helloworld "; +let document = "hello wOrld"; + +let characters = "hello"; +let document = "wOrld"; + +console.log(generateDocument(characters, document)); \ No newline at end of file diff --git a/Strings/groupAnagrams.js b/Strings/groupAnagrams.js new file mode 100644 index 00000000..d52ac048 --- /dev/null +++ b/Strings/groupAnagrams.js @@ -0,0 +1,17 @@ + +// ! O(w * n * log(n)) time | O(wn) space - where w is the number of words and n is the length of the longest word +function groupAnagrams(words) { + const anagrams = {}; + for(const word of words) { + const sortedWord = word.split('').sort().join(''); + if(sortedWord in anagrams) { + anagrams[sortedWord].push(word); + } else { + anagrams[sortedWord] = [word]; + } + } + return Object.values(anagrams); +} +const words = ["yo", "act", "flop", "tac", "foo", "cat", "oy", "olfp"]; + +console.log(groupAnagrams(words)); \ No newline at end of file diff --git a/Strings/longestPalindromeSubstring.js b/Strings/longestPalindromeSubstring.js new file mode 100644 index 00000000..d5c79f01 --- /dev/null +++ b/Strings/longestPalindromeSubstring.js @@ -0,0 +1,39 @@ +//! O(n^2) time | O(1) space +function longestPalindromicSubstring(string) { + let currentLongest = [0, 1]; + for(let i = 1; i < string.length; i++) { + const odd = getLongestPalindromeFrom(string, i - 1, i + 1); + const even = getLongestPalindromeFrom(string, i - 1, i); + const longest = odd[1] - odd[0] > even[1] - even[0] ? odd : even; + currentLongest = currentLongest[1] - currentLongest[0] > longest[1] - longest[0] ? currentLongest : longest; + } + return string.slice(currentLongest[0], currentLongest[1]); +} +function getLongestPalindromeFrom(string, leftIdx, rightIdx) { + while(leftIdx >= 0 && rightIdx < string.length) { + if (string[leftIdx] != string[rightIdx]) break; + leftIdx--; + rightIdx++; + } + return [leftIdx + 1, rightIdx]; +} + +//! O(n^2) time | O(1) space +function longestPalindromicSubstring(string) { + let currentLongest = [0, 1]; + for(let i = 1; i < string.length; i++) { + const odd = getLongestPalindromeFrom(string, i - 1, i + 1); + const even = getLongestPalindromeFrom(string, i - 1, i); + const longest = odd[1] - odd[0] > even[1] - even[0] ? odd : even; + currentLongest = currentLongest[1] - currentLongest[0] > longest[1] - longest[0] ? currentLongest : longest; + } + return string.slice(currentLongest[0], currentLongest[1]); +} +function getLongestPalindromeFrom(string, leftIdx, rightIdx) { + while(leftIdx >= 0 && rightIdx < string.length) { + if (string[leftIdx] != string[rightIdx]) break; + leftIdx--; + rightIdx++; + } + return [leftIdx + 1, rightIdx]; +} \ No newline at end of file diff --git a/Strings/longestSubstringWithoutDuplicates.js b/Strings/longestSubstringWithoutDuplicates.js new file mode 100644 index 00000000..3db0bc62 --- /dev/null +++ b/Strings/longestSubstringWithoutDuplicates.js @@ -0,0 +1,21 @@ +//! O(n) time | O(min(n, a)) space +function longestSubstringWithoutDuplication(string) { + const lastSeen = {}; + let longest = [0, 1]; + let startIdx = 0; + for(let i = 0; i < string.length; i++) { + const char = string[i]; + if(char in lastSeen) { + // startIdx = Math.max(startIdx, lastSeen[char] + 1); + startIdx = lastSeen[char] + 1; + console.log(startIdx) + } if(longest[1] - longest[0] < i + 1 - startIdx){ + longest = [startIdx, i+1]; + } + lastSeen[char] = i; + } + return string.slice(longest[0], longest[1]); + +} + +console.log(longestSubstringWithoutDuplication("clementisacap")) \ No newline at end of file diff --git a/Strings/minCharactersForWord.js b/Strings/minCharactersForWord.js new file mode 100644 index 00000000..02cca421 --- /dev/null +++ b/Strings/minCharactersForWord.js @@ -0,0 +1,58 @@ +//! O(n * l) time | O(c) space - where n is the number of words, +//! l is the length of the longest word, and c is the +//! number of unique characters across all words. + + +function minimumCharactersForWords(words) { + const maximumCharacterFrequencies = {}; + + for(const word of words) { + const characterFrequencies = countCharacterFrequencies(word); + updateMaximumCharacterFrequencies(characterFrequencies, maximumCharacterFrequencies); + } + + return makeArrayFromCharacterFrequencies(maximumCharacterFrequencies); +} + +function countCharacterFrequencies(string) { + const characterFrequencies = {}; + + for(const character of string) { + if(!(character in characterFrequencies)) characterFrequencies[character] = 0; + characterFrequencies[character] += 1; + } + return characterFrequencies; +} + +function updateMaximumCharacterFrequencies(frequencies, maximumFrequencies) { + + for(const character in frequencies) { + const frequency = frequencies[character]; + + if(character in maximumFrequencies) maximumFrequencies[character] = Math.max(maximumFrequencies[character], frequency); + else { + maximumFrequencies[character] = frequency; + } + + + + } +} + + +function makeArrayFromCharacterFrequencies(characterFrequencies) { + const characters = []; + for(const character in characterFrequencies) { + + const frequency = characterFrequencies[character]; + + for(let i = 0; i < frequency; i++) { + characters.push(character); + } + } + return characters; +} + + +const words = ["this", "that", "did", "deed", "them!", "a"]; +console.log(minimumCharactersForWords(words)); \ No newline at end of file diff --git a/Strings/palindromeCheck.js b/Strings/palindromeCheck.js new file mode 100644 index 00000000..cbe71d32 --- /dev/null +++ b/Strings/palindromeCheck.js @@ -0,0 +1,37 @@ + + //! O(n^2) time | O(n) space +function isPalindrome(string) { + let reversedString = ''; + for(let i = string.length - 1; i >= 0; i) { + reversedString += string[i]; + } + return string === reversedString; +} + +//! O(n) time | O(n) space +function isPalindrome(string) { + + const reversedChars = []; + for(let i = string.length - 1; i >= 0; i--) { + reversedChars.push(string[i]); + } + return string === reversedChars.join(''); +} + +//! O(n) time | O(n) space +function isPalindrome(string, i = 0) { + const j = string.length - 1 - i; + return i >= j ? true : string[i] === string[j] && isPalindrome(string, i + 1); +} + +//!O(n) time | O(1) space +function isPalindrome(string) { + let i = 0; + let j = string.length - 1; + while(i < j) { + if(string[i] != string[j]) return false; + i++; + j--; + } + return true; +} \ No newline at end of file diff --git a/Strings/reverseWordsInString.js b/Strings/reverseWordsInString.js new file mode 100644 index 00000000..4aec4c9a --- /dev/null +++ b/Strings/reverseWordsInString.js @@ -0,0 +1,26 @@ +//! O(n) time | O(n) space +function reverseWordsInString(string) { + const characters = []; + for(const char of string) + characters.push(char); +console.log(characters); + + reverseListRange(characters, 0, characters.length - 1); + + console.log(characters); +} + +function reverseListRange(list, start, end) { + + while(start < end) { + const temp = list[start]; + list[start] = list[end]; + list[end] = temp; + start++; + end--; + } +} +const words = "AlgoExpert is the best!"; + + +console.log(reverseWordsInString(words)); \ No newline at end of file diff --git a/Strings/runLengthEncoding.js b/Strings/runLengthEncoding.js new file mode 100644 index 00000000..3bfa1e9c --- /dev/null +++ b/Strings/runLengthEncoding.js @@ -0,0 +1,91 @@ +// function runLengthEncoding(string) { +// //!The input string is guaranteed to be non-empty, +// //! so first run will be of at least length 1. +// const encodedStringCharacters = []; +// let currentRunLength = 1; +// for(let i = 1; i < string.length; i++) { +// const currentCharacter = string[i]; +// const previousCharacter = string[i - 1]; + +// if(currentCharacter !== previousCharacter || currentRunLength == 9) { +// encodedStringCharacters.push(currentRunLength.toString()); +// encodedStringCharacters.push(previousCharacter); +// currentRunLength = 0; +// } +// currentRunLength++; +// } +// //! Handle the last run. +// encodedStringCharacters.push(currentRunLength.toString()); +// encodedStringCharacters.push(string[string.length - 1]); + +// return encodedStringCharacters.join(''); + +// } + +// //! myLogic : only working for few test cases. +// function runLengthEncoding(string) { +// let char = string[0]; +// let count = 1; +// let output = []; +// for(let i = 1; i <= string.length; i++) { +// if(char !== string[i]) { +// output.push(count + char); +// char = string[i]; +// count = 0; +// } +// if(char === string[i]) { +// count++; +// } +// if(count == 9) { +// let temp = count + char; +// output.push(temp); +// temp = ''; +// count = 0; +// } +// } +// return output.join(''); +// } + + +function runLengthEncoding(string) { + let resultStr = ""; + let counts = []; + let chars = []; + + for(let i = 0; i < string.length; i++) { + let j = i; + let char = string[i]; + let temp = 1; + while(char == string[j]) { + j++; + temp++; + } + counts.push(temp); + chars.push(string[i]); + i = j; + } + + + console.log(chars, counts) + for(let i = 0; i < counts.length; i++) { + if(counts[i] > 9) { + let k = counts[i] % 10; + let z = 9 + chars[i] + k + chars[i]; + resultStr += z; + } + else { + let a = counts[i] + chars[i]; + resultStr += a; + } + } + return resultStr; +} + +// Do not edit the line below. +exports.runLengthEncoding = runLengthEncoding; + + +// let str = 'AAAAAAAAAAAAABBCCCCDD'; +let str = 'aaAA'; + +console.log(runLengthEncoding(str)); \ No newline at end of file diff --git a/Strings/smallestSubstringContaining.js b/Strings/smallestSubstringContaining.js new file mode 100644 index 00000000..add44182 --- /dev/null +++ b/Strings/smallestSubstringContaining.js @@ -0,0 +1,73 @@ +//! https://www.algoexpert.io/questions/Smallest%20Substring%20Containing +//! https://leetcode.com/problems/minimum-window-substring/ + +function smallestSubstringContaining(bigString, smallString) { + const targetCharCounts = getCharCounts(smallString); + const substringBounds = getStringBounds(bigString, targetCharCounts); + return getStringFromBounds(bigString, substringBounds); +} + +function getCharCounts(string) { + const charCounts = {}; + for(const char of string) { + increaseCharCount(char, charCounts); + } + return charCounts; +} + +function getStringBounds(string, targetCharCounts) { + let subStringBounds = [0, Infinity]; + const subStringCharCounts = {}; + const numUniqueChars = Object.keys(targetCharCounts).length; + let numUniqueCharsDone = 0; + let leftIdx = 0; + let rightIdx =0; + + while(rightIdx < string.length) { + const rightChar = string[rightIdx]; + if(!(rightChar in targetCharCounts)) { + rightIdx++; + continue; + } + increaseCharCount(rightChar, subStringCharCounts); + if(subStringCharCounts[rightChar] == targetCharCounts[rightChar]) { + numUniqueCharsDone++; + } + while(numUniqueCharsDone === numUniqueChars && leftIdx <= rightIdx) { + subStringBounds = getCloserBounds(leftIdx, rightIdx, subStringBounds[0], subStringBounds[1]); + const leftChar = string[leftIdx]; + if(!(leftChar in targetCharCounts)) { + leftIdx++; + continue; + } + if(subStringCharCounts[leftChar] === targetCharCounts[leftChar]) { + numUniqueCharsDone--; + } + decreaseCharCount(leftChar, subStringCharCounts); + leftIdx++; + } + rightIdx++; + } + return subStringBounds; +} + +function getCloserBounds(idx1, idx2, idx3, idx4) { + return idx2 - idx1 < idx4 - idx3 ? [idx1, idx2] : [idx3, idx4]; +} + +function increaseCharCount(char, charCounts) { + charCounts[char] = (charCounts[char] || 0) + 1; +} + +function decreaseCharCount(char, charCounts) { + charCounts[char]--; +} + +function getStringFromBounds(string, bounds) { + const [start, end] = bounds; + if(end == Infinity) return ''; + return string.slice(start, end + 1); + } + + + console.log(smallestSubstringContaining("abcd$ef$axb$c$", "$$abf")); \ No newline at end of file diff --git a/Strings/tempCodeRunnerFile.js b/Strings/tempCodeRunnerFile.js new file mode 100644 index 00000000..4e15beea --- /dev/null +++ b/Strings/tempCodeRunnerFile.js @@ -0,0 +1 @@ +smallestSubstringContaining \ No newline at end of file diff --git a/Strings/validIPAddresses.js b/Strings/validIPAddresses.js new file mode 100644 index 00000000..45fcdbfe --- /dev/null +++ b/Strings/validIPAddresses.js @@ -0,0 +1,37 @@ +function validIPAddresses(string) { + const ipAddressesFound = []; + + for(let i = 0; i < Math.min(string.length, 4); i++) { + const currentIPAddressParts = ['', '', '', '']; + + currentIPAddressParts[0] = string.slice(0, i); + + if(!isValidPart(currentIPAddressParts[0])) continue; + + for(let j = i + 1; j < i + Math.min(string.length - i, 4); j++) { + currentIPAddressParts[1] = string.slice(i, j); + if(!isValidPart(currentIPAddressParts[1])) continue; + + for(let k = j + 1; k < j + Math.min(string.length - j, 4); k++) { + + currentIPAddressParts[2] = string.slice(j, k); + currentIPAddressParts[3] = string.slice(k); + if(!(isValidPart(currentIPAddressParts[2]) && isValidPart(currentIPAddressParts[3]))) continue; + + ipAddressesFound.push(currentIPAddressParts.join('.')); + } + } +} + return ipAddressesFound; +} + +function isValidPart(string) { + const stringAsInt = parseInt(string); + if(stringAsInt > 255) return false; + + return string.length == stringAsInt.toString().length; +} + +const string = '1921680'; + +console.log(validIPAddresses(string)); \ No newline at end of file diff --git a/Trees/.DS_Store b/Trees/.DS_Store new file mode 100644 index 00000000..211b4a3f Binary files /dev/null and b/Trees/.DS_Store differ diff --git a/Trees/Binary_Search_Trees/.DS_Store b/Trees/Binary_Search_Trees/.DS_Store new file mode 100644 index 00000000..5008ddfc Binary files /dev/null and b/Trees/Binary_Search_Trees/.DS_Store differ diff --git a/Trees/Binary_Search_Trees/BSTConsruction.js b/Trees/Binary_Search_Trees/BSTConsruction.js new file mode 100644 index 00000000..aaaf4488 --- /dev/null +++ b/Trees/Binary_Search_Trees/BSTConsruction.js @@ -0,0 +1,103 @@ +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } + + //! Average case: O(logn) time | O(1) space + //! worst case: O(n) time | O(1) space + insert(value) { + let currentNode = this; + while(true) { + if(value < currentNode.value ) { + if(currentNode.left == null) { + currentNode.left = new BST(value); + break; + } else { + currentNode = currentNode.left; + } + } else { + if(currentNode.right == null) { + currentNode.right = new BST(value); + break; + } else { + currentNode = currentNode.right; + } + } + } + return this; + } + +//! Average case: O(logn) time | O(1) space +//! worst case: O(n) time | O(1) space + +contains(value) { + let currentNode = this; + while(currentNode) { + if(value < currentNode.value) { + currentNode = currentNode.left; + } else if(value > currentNode) { + currentNode = currentNode.right; + } else { + return true; + } + } + return false; + } + +//! Average case: O(logn) time | O(1) space +//! worst case: O(n) time | O(1) space + +remove(value, parentNode = null) { + let currentNode = this; + while(currentNode) { + if(value < currentNode.value) { + parentNode = currentNode + currentNode = currentNode.left; + } else if(value > currentNode.value) { + parentNode = currentNode; + currentNode.right; + } else { + // node to remove + //If contains left and right + if(currentNode.left && currentNode.right) { + // get smallest value in the right subtree + currentNode.value = currentNode.right.getMinValue(); + //remove smallest value from right subtree + currentNode.right.remove(currentNode.value, currentNode); + } else if(parentNode == null) { // root node + // only left subtree + if(currentNode.left) { + currentNode.value = currentNode.left.value; + currentNode.right = currentNode.left.right; + currentNode.left = currentNode.left.left; + } else if(currentNode.right) { + currentNode.value = currentNode.right.value; + currentNode.left = currentNode.right.left; + currentNode.right = currentNode.right.right; + } else { + // only one node do nothing + } + + } // only left subtree + else if(parentNode.left == currentNode) { + parentNode.left = currentNode.left != null ? currentNode.left: currentNode.right; + } // only right subtree + else if(parentNode.right == currentNode) { + parentNode.right = currentNode.right != null ? currentNode.right: currentNode.left; + } + // we're done break the loop + break; + } + } + return this; +} +getMinValue() { + let currentNode = this; + while(currentNode.left) { + currentNode = currentNode.left; + } + return currentNode.value; +} +} \ No newline at end of file diff --git a/Trees/Binary_Search_Trees/bstTraversal.js b/Trees/Binary_Search_Trees/bstTraversal.js new file mode 100644 index 00000000..83d4009a --- /dev/null +++ b/Trees/Binary_Search_Trees/bstTraversal.js @@ -0,0 +1,32 @@ +//! O(n) time | O(n) space +function inOrderTraverse(tree, array) { + if(!tree) return; + + inOrderTraverse(tree.left, array); + array.push(tree.value); + inOrderTraverse(tree.right, array); + + return array; +} + +//! O(n) time | O(n) space +function preOrderTraverse(tree, array) { + if(!tree) return; + + array.push(tree.value); + preOrderTraverse(tree.left, array); + preOrderTraverse(tree.right, array); + + return array; +} + +//! O(n) time | O(n) space +function postOrderTraverse(tree, array) { + if(!tree) return; + + postOrderTraverse(tree.left, array); + postOrderTraverse(tree.right, array); + array.push(tree.value); + + return array; +} \ No newline at end of file diff --git a/Trees/Binary_Search_Trees/convertSortedArrayToBst.js b/Trees/Binary_Search_Trees/convertSortedArrayToBst.js new file mode 100644 index 00000000..daff3ddd --- /dev/null +++ b/Trees/Binary_Search_Trees/convertSortedArrayToBst.js @@ -0,0 +1,93 @@ +//! Also known as minHeightBst. +//! https://www.algoexpert.io/questions/Min%20Height%20BST +//! Google + +function minHeightBst(array) { + return constructMinHeightBst(array, 0, array.length - 1); +} + + +//! O(n) time | O(n) space | best approach +function constructMinHeightBst(array, startIdx, endIdx) { + if(endIdx < startIdx) return; + + const midIdx = Math.max((startIdx + endIdx) / 2); + const bst = new BST(array[midIdx]); + + bst.left = constructMinHeightBst(array, startIdx, midIdx - 1); + bst.left = constructMinHeightBst(array, midIdx + 1, endIdx); + + return bst; + +} + +function minHeightBst(array) { + return constructMinHeightBst(array, null, 0, array.length - 1); +} + +//! O(n) time | O(n) space +function constructMinHeightBst(array, bst, startIdx, endIdx) { + if(endIdx < startIdx) return; + + const midIdx = Math.max((startIdx + endIdx) / 2); + const newBstNode = new BST(array[midIdx]); + + if(!bst) bst = newBstNode; + else { + if(array[midIdx] < bst.value) { + bst.left = newBstNode; + bst = bst.left; + } else { + bst.right = newBstNode; + bst = bst.right; + } + } + constructMinHeightBst(array, bst, startIdx, midIdx - 1); + constructMinHeightBst(array, bst, midIdx + 1, endIdx); + + return bst; + +} + +//! O(nlogn) time | O(n) space +function constructMinHeightBst(array, bst, startIdx, endIdx) { + if(endIdx < startIdx) return; + + const midIdx = Math.max((startIdx + endIdx) / 2); + const valueToAdd = array[midIdx]; + + if(!bst) bst = new BST(valueToAdd); + else bst.insert(valueToAdd); + + constructMinHeightBst(array, bst, startIdx, midIdx - 1); + constructMinHeightBst(array, bst, midIdx + 1, endIdx); + + return bst; +} + +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } + + insert(value) { + if (value < this.value) { + if (this.left === null) { + this.left = new BST(value); + } else { + this.left.insert(value); + } + } else { + if (this.right === null) { + this.right = new BST(value); + } else { + this.right.insert(value); + } + } + } +} + +// Do not edit the line below. +exports.minHeightBst = minHeightBst; diff --git a/Trees/Binary_Search_Trees/findClosestValueInBst.js b/Trees/Binary_Search_Trees/findClosestValueInBst.js new file mode 100644 index 00000000..725ac955 --- /dev/null +++ b/Trees/Binary_Search_Trees/findClosestValueInBst.js @@ -0,0 +1,51 @@ + +function findClosestValueInBst(tree, target) { + return findClosestValueInBstHelper(tree, target, tree.value); +} + +//! worst case O(n)time | O(1) space +//! Avg case O(nlogn) time | O(1) space +function findClosestValueInBstHelper(tree, target, closest) { + + let currentNode = tree; + + while(currentNode) { + if(Math.abs(target - closest) > Math.abs(target - currentNode.value)) { + closest = currentNode.value; + } + + if(target < currentNode.value) { + currentNode = currentNode.left; + } else if(target > currentNode.value) { + currentNode = currentNode.right; + } else { + break; + } + return closest; + } +} + +//! worst case O(n)time | O(n) space +//! Avg case O(nlogn) time | O(logn) space +function findClosestValueInBstHelper(tree, target, closest) { + if(!tree) return closest; + + if(Math.abs(target - closest) > Math.abs(target - tree.value)) { + closest = tree.value; + } + + if(target < tree.value) { + return findClosestValueInBstHelper(tree.left, target, closest); + } else if(target > tree.value) { + return findClosestValueInBstHelper(tree.right, target, closest); + } + return closest; + +} +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} diff --git a/Trees/Binary_Search_Trees/greatesstSumTree.js b/Trees/Binary_Search_Trees/greatesstSumTree.js new file mode 100644 index 00000000..23681d20 --- /dev/null +++ b/Trees/Binary_Search_Trees/greatesstSumTree.js @@ -0,0 +1,43 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +function preOrder(root) { + if(root == null) return; + console.log(root.data); + preOrder(root.left); + preOrder(root.right); +} + +let sum_of_nodes = 0; +function greatestSumTree(root) { + if(root == null) return; + greatestSumTree(root.right); + sum_of_nodes += root.data; + root.data = sum_of_nodes; + greatestSumTree(root.left); + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +preOrder(root); +console.log("-->"); +greatestSumTree(root); +console.log("-->"); +preOrder(root); diff --git a/Trees/Binary_Search_Trees/kthLargestValueInBst.js b/Trees/Binary_Search_Trees/kthLargestValueInBst.js new file mode 100644 index 00000000..762d7641 --- /dev/null +++ b/Trees/Binary_Search_Trees/kthLargestValueInBst.js @@ -0,0 +1,21 @@ +//! O(n) time | O(n) space | worst approach + +function findKthLargestValueInBst(tree, k) { + const sortedNodeValues = []; + inOrderTraverse(tree, sortedNodeValues); +} + +function inOrderTraverse(node, sortedNodeValues) { + if(!node) return; + + inOrderTraverse(node.left, sortedNodeValues); + sortedNodeValues.push(node.value); + inOrderTraverse(node.right, sortedNodeValues); +} +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} \ No newline at end of file diff --git a/Trees/Binary_Search_Trees/minHeightBst.js b/Trees/Binary_Search_Trees/minHeightBst.js new file mode 100644 index 00000000..2bfea5c4 --- /dev/null +++ b/Trees/Binary_Search_Trees/minHeightBst.js @@ -0,0 +1 @@ +//! AVL Tree \ No newline at end of file diff --git a/Trees/Binary_Search_Trees/reconstructBst.js b/Trees/Binary_Search_Trees/reconstructBst.js new file mode 100644 index 00000000..c86d48d1 --- /dev/null +++ b/Trees/Binary_Search_Trees/reconstructBst.js @@ -0,0 +1,37 @@ +//! aka pre-order to BST + +//! O(n) time | O(n) space + +class BST { + constructor(value, left = null, right = null) { + this.value = value; + this.left = left; + this.right = right; + } +} + +class TreeInfo { + constructor(rootIdx) { + this.rootIdx = rootIdx; + } +} + +function reconstructBst(preOrderTraversalValues) { + const treeInfo = new TreeInfo(0); + return reconstructBstFromRange(-Infinity, Infinity, preOrderTraversalValues, treeInfo); +} + +function reconstructBstFromRange(lowerBound, upperBound, preOrderTraversalValues, currentSubtreeInfo) { + if(currentSubtreeInfo.rootIdx == preOrderTraversalValues.length) return null; + + const rootValue = preOrderTraversalValues[currentSubtreeInfo.rootIdx]; + if(rootValue < lowerBound || rootValue >= upperBound) return null; + + currentSubtreeInfo.rootIdx++; + + const leftSubtree = reconstructBstFromRange(lowerBound, rootValue, preOrderTraversalValues, currentSubtreeInfo); + const rightSubtree = reconstructBstFromRange(rootValue, upperBound, preOrderTraversalValues, currentSubtreeInfo); + + return new BST(rootValue, leftSubtree, rightSubtree); +} + diff --git a/Trees/Binary_Search_Trees/rightSmallerThan.js b/Trees/Binary_Search_Trees/rightSmallerThan.js new file mode 100644 index 00000000..9e5f82a0 --- /dev/null +++ b/Trees/Binary_Search_Trees/rightSmallerThan.js @@ -0,0 +1,68 @@ +//! https://leetcode.com/problems/count-of-smaller-numbers-after-self/ +//! https://www.algoexpert.io/questions/Right Smaller Than + +//! Avg case: O(nlog(n)) time | O(n) space +//! Worst case: O(n^2) time | O(n) space + +function rightSmallerThan(array) { + if(array.length == 0) return []; + + const lastIdx = array.length - 1; + const bst = new SpecialBST(array[lastIdx], lastIdx, 0); + for(let i = array.length - 2; i > -1; i--) { + bst.insert(array[i], i); + } + + const rightSmallerCounts = array.slice(); + getRightSmallerCounts(bst, rightSmallerCounts); + return rightSmallerCounts; +} + +function getRightSmallerCounts(bst, rightSmallerCounts) { + if(bst == null) return; + rightSmallerCounts[bst.idx] = bst.numSmallerAtInsertTime; + getRightSmallerCounts(bst.left, rightSmallerCounts); + getRightSmallerCounts(bst.right, rightSmallerCounts); +} + +class SpecialBST { + constructor(value, idx, numSmallerAtInsertTime) { + this.value = value; + this.idx = idx; + this.numSmallerAtInsertTime = numSmallerAtInsertTime; + this.leftSubtreeSize = 0; + this.left = null; + this.right = null; + } + + insert(value, idx, numSmallerAtInsertTime = 0) { + if(value < this.value) { + this.leftIdxSubtree++; + if(this.left == null) { + this.left = new SpecialBST(value, idx, numSmallerAtInsertTime); + } else { + this.left.insert(value, idx, numSmallerAtInsertTime); + } + } else { + if(value > this.value) numSmallerAtInsertTime++; + if(this.right = null) { + this.right = new SpecialBST(value, idx, numSmallerAtInsertTime); + } else { + this.right.insert(value, idx, numSmallerAtInsertTime); + } + } + } +} + +//! O(n^2) time | O(n) space +function rightSmallerThan(array) { + const rightSmallerCounts = []; + for(let i = 0; i < array.length; i++) { + let rightSmallerCount = 0; + for(let j = i + 1; j < array.length; j++) { + if(array[i] > array[j]) rightSmallerCount++; + } + rightSmallerCounts.push(rightSmallerCount); + } + return rightSmallerCounts; +} \ No newline at end of file diff --git a/Trees/Binary_Search_Trees/sameBsts.js b/Trees/Binary_Search_Trees/sameBsts.js new file mode 100644 index 00000000..37c1d523 --- /dev/null +++ b/Trees/Binary_Search_Trees/sameBsts.js @@ -0,0 +1,39 @@ +//! https://www.algoexpert.io/questions/Same%20BSTs +//! O(n^2) time | O(n^2) space + +function sameBsts(arrayOne, arrayTwo) { + + if(arrayOne.length != arrayTwo.length) return false; + + if(arrayOne.length == 0 && arrayTwo.length == 0) return true; + + if(arrayOne[0] != arrayTwo[0]) return false; + + const leftOne = getSmaller(arrayOne); + const leftTwo = getSmaller(arrayTwo); + + const rightOne = getBigger(arrayOne); + const rightTwo = getBigger(arrayTwo); + + return sameBsts(leftOne, leftTwo) && sameBsts(rightOne, rightTwo); + + +} + +function getSmaller(array) { + const smaller = []; + + for(let i = 1; i < array.length; i++) { + if(array[i] < array[0]) smaller.push(array[i]); + } + return smaller; +} + +function getBigger(array) { + const bigger = []; + + for(let i = 1; i < array.length; i++) { + if(array[i] >= array[0]) bigger.push(array[i]); + } + return bigger; +} \ No newline at end of file diff --git a/Trees/Binary_Search_Trees/validateBst.js b/Trees/Binary_Search_Trees/validateBst.js new file mode 100644 index 00000000..2d32e7f8 --- /dev/null +++ b/Trees/Binary_Search_Trees/validateBst.js @@ -0,0 +1,21 @@ +// ! O(n) time | O(d) space d = depth/height of tree + +class BST { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +function validateBst(tree) { + return validateBstHelper(tree, -Infinity, Infinity); +} + +function validateBstHelper(tree, minValue, maxValue) { + if(!tree) return true; + + if(tree.value < minValue || tree.value >= maxValue) return false; + const isLeftValid = validateBstHelper(tree.left, minValue, tree.value); + return isLeftValid && validateBstHelper(tree.right, tree.value, maxValue); +} \ No newline at end of file diff --git a/Trees/Binary_Search_Trees/validateThreeNodes.js b/Trees/Binary_Search_Trees/validateThreeNodes.js new file mode 100644 index 00000000..372777af --- /dev/null +++ b/Trees/Binary_Search_Trees/validateThreeNodes.js @@ -0,0 +1,18 @@ + +//! O(h) time | (h) space +function validateThreeNodes(nodeOne, nodeTwo, nodeThree) { + + if(isDescedant(nodeTwo, nodeOne)) return isDescedant(nodeTwo, nodeThree); + + if(isDescedant(nodeTwo, nodeThree)) return isDescedant(nodeOne, nodeTwo); + + return false; +} + +function isDescedant(node, target) { + if(!node) return false; + + if(node == target) return true; + + return target.value < node.value ? isDescedant(node.left, target) : isDescedant(node.right, target); +} \ No newline at end of file diff --git a/Trees/Binary_Trees/allKindsOfNodesDepths.js b/Trees/Binary_Trees/allKindsOfNodesDepths.js new file mode 100644 index 00000000..73c16703 --- /dev/null +++ b/Trees/Binary_Trees/allKindsOfNodesDepths.js @@ -0,0 +1,11 @@ +//! o(n^2) time | O(n) space + +function allKindsOfNodeDepths(root) { + if(!root) return 0; + return allKindsOfNodeDepths(root.left) + allKindsOfNodeDepths(root.right) + nodeDepths(root); +} + +function nodeDepths(root, depth = 0) { + if(!root) return 0; + return depth + nodeDepths(root.left, depth + 1) + nodeDepths(root.right, depth + 1); +} \ No newline at end of file diff --git a/Trees/Binary_Trees/binaryTreeDiameter.js b/Trees/Binary_Trees/binaryTreeDiameter.js new file mode 100644 index 00000000..3d91779f --- /dev/null +++ b/Trees/Binary_Trees/binaryTreeDiameter.js @@ -0,0 +1,36 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +class TreeInfo { + constructor(diameter, height) { + this.diameter = diameter; + this.height = height; + } +} + +//! O(n) time | O(h) space +function binaryTreeDiameter(tree) { + return getTreeInfo(tree).diameter; +} + +function getTreeInfo(tree) { + + if(!tree) return new TreeInfo(0, 0); + + const leftTreeInfo = getTreeInfo(tree.left); + const rightTreeInfo = getTreeInfo(tree.right); + + const longestPathThroughRoot = leftTreeInfo.height + rightSubTree.height; + const maxDiameterSoFar = Math.max(leftTreeInfo.diameter, rightTreeInfo.diameter); + + const currentDiameter = Math.max(maxDiameterSoFar, longestPathThroughRoot); + const currentHeight = 1 + Math.max(leftTreeInfo.height, rightTreeInfo.height); + + return new TreeInfo(currentDiameter, currentHeight); +} + diff --git a/Trees/Binary_Trees/branchSums.js b/Trees/Binary_Trees/branchSums.js new file mode 100644 index 00000000..43f4df16 --- /dev/null +++ b/Trees/Binary_Trees/branchSums.js @@ -0,0 +1,52 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +function branchSums(root) { + + const sums = []; + calculateBranchSums(root, 0, sums); + + return sums; + +} + + +function calculateBranchSums(node, runningSum, sums) { + + if(!node) return; + + const newRunningSum = runningSum + node.value; + + + if(!node.left && !node.right) { + sums.push(newRunningSum); + return; + } + calculateBranchSums(node.left, newRunningSum, sums); + calculateBranchSums(node.right, newRunningSum, sums); +} + + +const root = new BinaryTree(1); + +root.left = new BinaryTree(2); +root.right = new BinaryTree(3); + +root.left.left = new BinaryTree(4); +root.left.right = new BinaryTree(5); + +root.left.right.left = new BinaryTree(10); + +root.left.left.left = new BinaryTree(8); +root.left.left.right = new BinaryTree(9); + +root.right.left = new BinaryTree(6); +root.right.right = new BinaryTree(7); + + +console.log(branchSums(root)); \ No newline at end of file diff --git a/Trees/Binary_Trees/breadthFirstSearch.js b/Trees/Binary_Trees/breadthFirstSearch.js new file mode 100644 index 00000000..cdad14dd --- /dev/null +++ b/Trees/Binary_Trees/breadthFirstSearch.js @@ -0,0 +1,62 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } +} + +function levelOrderTraversal(root) { + let queue = new Queue(); + queue.enqueue(root); + + while(!queue.isEmpty()) { + let current = queue.dequeue(); + console.log(current.data); + + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.right = new Node(50); +root.right.left = new Node(60); +root.right.right = new Node(70); + +levelOrderTraversal(root); \ No newline at end of file diff --git a/Trees/Binary_Trees/campareLeafTraversal.js b/Trees/Binary_Trees/campareLeafTraversal.js new file mode 100644 index 00000000..7539f6d5 --- /dev/null +++ b/Trees/Binary_Trees/campareLeafTraversal.js @@ -0,0 +1,41 @@ +//! https://www.algoexpert.io/questions/Compare%20Leaf%20Traversal + +//! Google on-site + +//! O(n + m) time | O(max(h1, h2)) space + +function compareLeafTraversal(tree1, tree2) { + const [tree1LeafNodesLinkedList, _1] = connectNodes(tree1); + const [tree2LeafNodesLinkedList, _2] = connectNodes(tree2); + + let list1CurrentNode = tree1LeafNodesLinkedList; + let list2CurrentNode = tree2LeafNodesLinkedList; + + while(list1CurrentNode && list1CurrentNode) { + if(list1CurrentNode.value != list2CurrentNode.value) return false; + + list1CurrentNode = list1CurrentNode.right; + list2CurrentNode = list2CurrentNode.right; + } + return !list1CurrentNode && !list2CurrentNode; +} + +function connectNodes(currentNode, head = null, previousNode = null) { + if(!currentNode) return [head, previousNode]; + + if(isLeafNode(currentNode)) { + if(previousNode == null) { + head = currentNode; + } else { + previousNode.right = currentNode; + } + previousNode = currentNode; + } + + const [leftHead, leftPreviousNode] = connectNodes(currentNode.left, head, previousNode); + return connectNodes(currentNode.right, leftHead, leftPreviousNode); +} + +function isLeafNode(node) { + return !node.left && !node.right; +} \ No newline at end of file diff --git a/Trees/Binary_Trees/checkMirror.js b/Trees/Binary_Trees/checkMirror.js new file mode 100644 index 00000000..faebca69 --- /dev/null +++ b/Trees/Binary_Trees/checkMirror.js @@ -0,0 +1,29 @@ +//!12/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +function isMirror(a, b) { + if(a == null && b == null) return true; + if(a == null || b == null) return false; + + + return a.data == b.data && a.left == b.left && a.right == b.left; + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +console.log(isMirror(root, root)); \ No newline at end of file diff --git a/Trees/Binary_Trees/checkbinaryTreeIsBST.js b/Trees/Binary_Trees/checkbinaryTreeIsBST.js new file mode 100644 index 00000000..d478ee8c --- /dev/null +++ b/Trees/Binary_Trees/checkbinaryTreeIsBST.js @@ -0,0 +1,23 @@ +//! 15/02/2022 + +function isBST(root) { + if(root == null) { + return {max: Number.MIN_SAFE_INTEGER, min: Number.MAX_SAFE_INTEGER, isBst: true} + } + + let left = isBST(root.left); + let right = isBST(root.right); + if(left.isBst == true && right.isBst == true && root.data > left.max && root.data < right.min) { + return { + max: Math.max(left.max, right.max, root.data), + min: Math.min(left.min, right.min, root.data), + isBst: true + } + } else { + return { + max: Math.max(left.max, right.max, root.data), + min: Math.min(left.min, right.min, root.data), + isBst: false + } + } +} \ No newline at end of file diff --git a/Trees/Binary_Trees/constructBinary.js b/Trees/Binary_Trees/constructBinary.js new file mode 100644 index 00000000..78db76c8 --- /dev/null +++ b/Trees/Binary_Trees/constructBinary.js @@ -0,0 +1,90 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear] = element; + this.rear++; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front]; + this.front++; + return temp; + } else { + return undefined; + } + } +} + +class node { + constructor(d) { + this.data = d; + this.left = null; + this.right = null; + } +} + +function levelOrderLevelWise(root) { + let qu = new Queue(); + let null_node = new node(null); + qu.enqueue(root); + qu.enqueue(null_node); + let result = ""; + while(!qu.isEmpty()) { + let curr = qu.dequeue(); + if(curr.data == null) { + // this is the end of the last level; + if(!qu.isEmpty()) { + qu.enqueue(new node(null)); + result += "\n"; + } + } else { + result += (curr.data + " "); + } + if(curr.left != null) { + qu.enqueue(curr.left); + } + if(curr.right != null) { + qu.enqueue(curr.right); + } + } + console.log(result); +} + +//! 15/02/2022 + +let preorderIndex = 0; +function search(inorder, l, r, data) { + for(let i = l; i <= r; i++) { + if(inorder[i] == data) return i; + } +} + +function buildTree(preorder, inorder, l, r) { + if(l > r) return null; + let newNode = new node(preorder[preorderIndex]); + preorderIndex++; + let inorderIndex = search(inorder, l, r, newNode.data); + newNode.left = buildTree(preorder, inorder, l, inorderIndex-1); + newNode.right = buildTree(preorder, inorder, inorderIndex+1, r); + return newNode; +} + +let pre = [3,9,20,15,7]; +let ino = [9,3,15,20,7]; + +let treenode = buildTree(pre, ino, 0, pre.length-1); +levelOrderLevelWise(treenode); diff --git a/Trees/Binary_Trees/dummy.js b/Trees/Binary_Trees/dummy.js new file mode 100644 index 00000000..7a8df829 --- /dev/null +++ b/Trees/Binary_Trees/dummy.js @@ -0,0 +1,60 @@ +class BinaryTree { + + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } + +} + + +function branchSums(root) { + + let sums = []; + + calculateBranchSums(root, 0, sums); + + return sums; +} + +function calculateBranchSums(node, runningSum, sums) { + + if(!node) return; + + const newRunningSum = runningSum + node.value; + + if(!node.left && !node.right) { + sums.push(newRunningSum); + return; + + } + + calculateBranchSums(node.left, newRunningSum, sums); + node.left = sums.pop(); + calculateBranchSums(node.right, newRunningSum, sums); + node.right = sums.pop(); + + +} + + + +const root = new BinaryTree(1); + +root.left = new BinaryTree(2); +root.right = new BinaryTree(3); + +root.left.left = new BinaryTree(4); +root.left.right = new BinaryTree(5); + +root.left.right.left = new BinaryTree(10); + +root.left.left.left = new BinaryTree(8); +root.left.left.right = new BinaryTree(9); + +root.right.left = new BinaryTree(6); +root.right.right = new BinaryTree(7); + + +console.log(branchSums(root)); \ No newline at end of file diff --git a/Trees/Binary_Trees/findHeight.js b/Trees/Binary_Trees/findHeight.js new file mode 100644 index 00000000..6948b419 --- /dev/null +++ b/Trees/Binary_Trees/findHeight.js @@ -0,0 +1,30 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +function height(root) { + // if(root.left == null && root.right == null) return 0; + + if(root == null) return -1; + + let leftHeight = height(root.left); + let rightHeight = height(root.right); + return Math.max(leftHeight, rightHeight) + 1; +} + + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +console.log(height(root)); diff --git a/Trees/Binary_Trees/findMaxElement.js b/Trees/Binary_Trees/findMaxElement.js new file mode 100644 index 00000000..f3b24c24 --- /dev/null +++ b/Trees/Binary_Trees/findMaxElement.js @@ -0,0 +1,28 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + + +function findMaxElement(root) { + if(root == null) return Number.MIN_SAFE_INTEGER; + + let leftMaxElement = findMaxElement(root.left); + let rightMaxElement = findMaxElement(root.right); + + return Math.max(leftMaxElement, rightMaxElement, root.data); +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +console.log(findMaxElement(root)); diff --git a/Trees/Binary_Trees/findNodesDistanceK.js b/Trees/Binary_Trees/findNodesDistanceK.js new file mode 100644 index 00000000..f0d2a5b5 --- /dev/null +++ b/Trees/Binary_Trees/findNodesDistanceK.js @@ -0,0 +1,50 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = left; + this.right = right; + } +} + +//! O(n) time | O(n) space + +function findNodesDistanceK(tree, target, k) { + const nodesDistanceK = []; + findNodesDistanceKHelper(tree, target, k, nodesDistanceK); + return nodesDistanceK; +} + +function findNodesDistanceKHelper(node, target, k, nodesDistanceK) { + + if(!node) return -1; + + if(node == target) { + addSubtreeNodesAtDistanceK(node, 0, k, nodesDistanceK); + return 1; + } + + const leftDistance = findNodesDistanceKHelper(node.left, target, k, nodesDistanceK); + const rightDistance = findNodesDistanceKHelper(node.right, target, k, nodesDistanceK); + + if(leftDistance == k || rightDistance == k) nodesDistanceK.push(node.value); + + if(leftDistance != -1) { + addSubtreeNodesAtDistanceK(node.right, leftDistance + 1, k, nodesDistanceK); + return leftDistance + 1; + } + if(rightDistance != -1) { + addSubtreeNodesAtDistanceK(node.left, rightDistance + 1, k, nodesDistanceK); + return rightDistance + 1; + } + return -1; +} + +function addSubtreeNodesAtDistanceK(node, distance, k, nodesDistanceK) { + if(!node) return; + + if(distance == k) nodesDistanceK.push(node.value); + else { + addSubtreeNodesAtDistanceK(node.left, distance + 1, k, nodesDistanceK); + addSubtreeNodesAtDistanceK(node.right, distance + 1, k, nodesDistanceK); + } +} \ No newline at end of file diff --git a/Trees/Binary_Trees/findPath.js b/Trees/Binary_Trees/findPath.js new file mode 100644 index 00000000..345a18eb --- /dev/null +++ b/Trees/Binary_Trees/findPath.js @@ -0,0 +1,59 @@ +//! 15/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +let preorderIndex = 0; +function search(inorder, l, r, data) { + for(let i = l; i <= r; i++) { + if(inorder[i] == data) return i; + } +} +function buildTree(preorder, inorder, l, r) { + if(l > r) return null; + let newNode = new Node(preorder[preorderIndex]); + preorderIndex++; + let inorderIndex = search(inorder, l, r, newNode.data); + newNode.left = buildTree(preorder, inorder, l, inorderIndex-1); + newNode.right = buildTree(preorder, inorder, inorderIndex+1, r); + return newNode; +} + + +function findPath(root, target, array) { + if(root == null) return false; + array.push(root.data); + if(root.data == target) return true; + if(findPath(root.left, target, array) || findPath(root.right, target, array)) + return true; + + array.pop(); + return false; + +} + +let pre = [3,9,20,15,7]; +let ino = [9,3,15,20,7]; + +let treeNode = buildTree(pre, ino, 0, pre.length-1); +// levelOrderLevelWise(treenode); + +let array = []; +findPath(treeNode, 15, array); +console.log(array); + +const root = new Node(1); +root.left = new Node(2); +root.right = new Node(3); +root.left.left = new Node(4); +root.left.right = new Node(5); +root.left.left.left = new Node(8); +root.left.left.right = new Node(9); +root.right.left = new Node(6); +root.right.right = new Node(7); diff --git a/Trees/Binary_Trees/findSuccessor.js b/Trees/Binary_Trees/findSuccessor.js new file mode 100644 index 00000000..f1db7933 --- /dev/null +++ b/Trees/Binary_Trees/findSuccessor.js @@ -0,0 +1,65 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + this.parent = null; + } +} + +//! O(n) time | O(1) space + +function findSuccessor(tree, node) { + + if(node.right) return getLeftmostChild(node.right); + + return getRightmostParent(node); +} + +function getLeftmostChild(node) { + let currentNode = node; + + while(currentNode.left) { + currentNode = currentNode.left; + } + return currentNode; +} + +function getRightmostParent(node) { + const currentNode = node; + + while(currentNode.parent && currentNode.parent.right == currentNode) { + currentNode = currentNode.parent; + } + return currentNode.parent; +} + + +//! O(n) time | O(h) space +function findSuccessor(tree, node) { + + const inOrderTraversalOrder = getInorderTraversalOrder(tree); + + for(let idx = 0; idx < inOrderTraversalOrder.length; idx++) { + const currentNode = inOrderTraversalOrder[idx]; + + if(currentNode != node) continue; + + if(idx == inOrderTraversalOrder.length - 1) return null; + + return inOrderTraversalOrder[idx + 1]; + } + + +} + +function getInorderTraversalOrder(node, order = []) { + + if(!node) return order; + + getInorderTraversalOrder(node.left, order); + order.push(node); + getInorderTraversalOrder(node.right, order); + + return order; +} \ No newline at end of file diff --git a/Trees/Binary_Trees/flattenBinaryTree.js b/Trees/Binary_Trees/flattenBinaryTree.js new file mode 100644 index 00000000..705c5f7b --- /dev/null +++ b/Trees/Binary_Trees/flattenBinaryTree.js @@ -0,0 +1,59 @@ +// ! https://www.algoexpert.io/questions/Flatten%20Binary%20Tree + + +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +//! O(n) time | O(d) space d - depth of binary tree +function flattenBinaryTree(root) { + const [leftMost, _] = flattenTree(root); + return leftMost; +} + +function flattenTree(node) { + let leftMost, rightMost; + if(!node.left) leftMost = node; + else { + const [leftSubtreeLeftMost, leftSubtreeRightMost] = flattenTree(node.left); + connectNodes(leftSubtreeRightMost, node); + leftMost = leftSubtreeLeftMost; + } + if(!node.right) rightMost = node; + else { + const [rightSubtreeLeftMost, rightSubtreeRightMost] = flattenTree(node.right); + connectNodes(node, rightSubtreeLeftMost); + rightMost = rightSubtreeRightMost; + } + return [leftMost, rightMost]; +} + +function connectNodes(left, right) { + left.right = right; + right.left = left; +} + +//! O(n) time | O(n) space +function flattenBinaryTree(root) { + const inOrderNodes = getNodesInorder(root, []); + for(let i = 0; i < inOrderNodes.length - 1; i++) { + const leftNode = inOrderNodes[i]; + const rightNode = inOrderNodes[i + 1]; + leftNode.right = rightNode; + rightNode.left = leftNode; + } + return inOrderNodes[0]; +} + +function inOrderNodes(tree, array) { + if(!tree) return; + inOrderNodes(tree.left, array); + array.push(tree); + inOrderNodes(tree.right, array); + return array; +} + diff --git a/Trees/Binary_Trees/flattenBinaryTree_leetcode.js b/Trees/Binary_Trees/flattenBinaryTree_leetcode.js new file mode 100644 index 00000000..5b168ff0 --- /dev/null +++ b/Trees/Binary_Trees/flattenBinaryTree_leetcode.js @@ -0,0 +1,38 @@ +//! https://leetcode.com/problems/flatten-binary-tree-to-linked-list/ + +//! RIGHT ROOT LEFT +//! O(n) time | O(n) space + +//! REVERSE POST ORDER +let previousNode = null; +function flatten(node) { + if(!node) return; + + flatten(node.right); + flatten(node.left); + + node.right = previousNode; + node.left = null; + previousNode = node; +} + +//! O(n) time O(1) space +function flatten(root) { + let currentNode = root; + let prev = null; + while(currentNode) { + if(currentNode.left) { + prev = currentNode.left; + while(prev.right) { + prev = prev.right; + } + prev.right = currentNode.right; + currentNode.right = currentNode.left; + currentNode.left = null; + } + currentNode = currentNode.right; + } +}; + + + diff --git a/Trees/Binary_Trees/heightBalancedBinaryTree.js b/Trees/Binary_Trees/heightBalancedBinaryTree.js new file mode 100644 index 00000000..b36963aa --- /dev/null +++ b/Trees/Binary_Trees/heightBalancedBinaryTree.js @@ -0,0 +1,36 @@ +class Tree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +class TreeInfo { + constructor(isBalanced, height) { + this.isBalanced = isBalanced; + this.height = height; + } +} + +//! O(n) time | O(h) space +function heightBalancedBinaryTree(tree) { + const treeInfo = getTreeInfo(tree); + return treeInfo.isBalanced; +} + +function getTreeInfo(tree) { + if(!tree) return new TreeInfo(true, -1); + + const leftSubtreeInfo = getLeftSubtreeInfo(tree.left); + const rightSubtreeInfo = getLeftSubtreeInfo(tree.right); + + const isBalanced = + leftSubtreeInfo.isBalanced && + rightSubtreeInfo.isBalanced && + Math.abs(leftSubtreeInfo.height - rightSubtreeInfo.height) <= 1; + + const height = Math.max(leftSubtreeInfo.height, rightSubtreeInfo.height) + 1; + + return new TreeInfo(isBalanced, height); +} \ No newline at end of file diff --git a/Trees/Binary_Trees/invertBinaryTree.js b/Trees/Binary_Trees/invertBinaryTree.js new file mode 100644 index 00000000..5a4af136 --- /dev/null +++ b/Trees/Binary_Trees/invertBinaryTree.js @@ -0,0 +1,26 @@ + +//! O(n) time | O(n) space +function invertBinaryTree(tree) { + const queue = [tree]; + + while(queue.length) { + const current = queue.shift(); + + if(current == null) continue; + + swapLeftAndRight(current); + queue.push(current.left); + queue.push(current.right); + } +} +//! O(n) time | O(n) space +function invertBinaryTree(tree) { + if(!tree) return; + + swapLeftAndRight(tree); + invertBinaryTree(tree.left); + invertBinaryTree(tree.right); +} +function swapLeftAndRight(tree){ + [tree.left, tree.right] = [tree.left, tree.right]; +} \ No newline at end of file diff --git a/Trees/Binary_Trees/iterativeInOrderTraversal.js b/Trees/Binary_Trees/iterativeInOrderTraversal.js new file mode 100644 index 00000000..1d2aa3cd --- /dev/null +++ b/Trees/Binary_Trees/iterativeInOrderTraversal.js @@ -0,0 +1,25 @@ +//! O(n) time | O(1) space + +function iterativeInOrderTraversal(tree, callback) { + let previousNode = null; + let currentNode = tree; + + while(currentNode) { + let nextNode; + if(!previousNode || previousNode == currentNode.parent) { + if(currentNode.left) { + nextNode = currentNode.left; + } else { + callback(currentNode); + nextNode = currentNode.right ? currentNode.right : currentNode.parent; + } + } else if(previousNode == currentNode.left) { + callback(currentNode); + nextNode = currentNode.right ? currentNode.right : currentNode.parent; + } else { + nextNode = currentNode.parent; + } + previousNode = currentNode; + currentNode = nextNode; + } +} \ No newline at end of file diff --git a/Trees/Binary_Trees/levelOrderLevelWise 2.js b/Trees/Binary_Trees/levelOrderLevelWise 2.js new file mode 100644 index 00000000..2c766337 --- /dev/null +++ b/Trees/Binary_Trees/levelOrderLevelWise 2.js @@ -0,0 +1,88 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + + +function levelOrderLevelWise(root) { + + let queue = new Queue(); + let null_node = new Node(null); + queue.enqueue(root); + queue.enqueue(null_node); + let result = ""; + while(!queue.isEmpty()) { + let current = queue.dequeue(); + if(current.data == null) { + if(!queue.isEmpty()) { + queue.enqueue(new Node(null)); + result += "\n"; + } + } else { + result += (current.data + " "); + } + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } + console.log(result); + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +levelOrderLevelWise(root); + + + diff --git a/Trees/Binary_Trees/levelOrderLevelWise.js b/Trees/Binary_Trees/levelOrderLevelWise.js new file mode 100644 index 00000000..c52bacb6 --- /dev/null +++ b/Trees/Binary_Trees/levelOrderLevelWise.js @@ -0,0 +1,63 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + + +function levelOrderLevelWise(root) { + + + +} +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + + + diff --git a/Trees/Binary_Trees/lowestCommonAncestor.js b/Trees/Binary_Trees/lowestCommonAncestor.js new file mode 100644 index 00000000..4bed8079 --- /dev/null +++ b/Trees/Binary_Trees/lowestCommonAncestor.js @@ -0,0 +1,110 @@ +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear] = element; + this.rear++; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front]; + this.front++; + return temp; + } else { + return undefined; + } + } +} + +class node { + constructor(d) { + this.data = d; + this.left = null; + this.right = null; + } +} + +function levelOrderLevelWise(root) { + let qu = new Queue(); + let null_node = new node(null); + qu.enqueue(root); + qu.enqueue(null_node); + let result = ""; + while(!qu.isEmpty()) { + let curr = qu.dequeue(); + if(curr.data == null) { + // this is the end of the last level; + if(!qu.isEmpty()) { + qu.enqueue(new node(null)); + result += "\n"; + } + } else { + result += (curr.data + " "); + } + if(curr.left != null) { + qu.enqueue(curr.left); + } + if(curr.right != null) { + qu.enqueue(curr.right); + } + } + console.log(result); +} + +//! 15/02/2022 + +let preorderIndex = 0; +function search(inorder, l, r, data) { + for(let i = l; i <= r; i++) { + if(inorder[i] == data) return i; + } +} + +function buildTree(preorder, inorder, l, r) { + if(l > r) return null; + let newNode = new node(preorder[preorderIndex]); + preorderIndex++; + let inorderIndex = search(inorder, l, r, newNode.data); + newNode.left = buildTree(preorder, inorder, l, inorderIndex-1); + newNode.right = buildTree(preorder, inorder, inorderIndex+1, r); + return newNode; +} + +let lca_ans = null; +function lca(root, p, q) { + if(root == null) return 0; + let left = lca(root.left, p, q); + let right = lca(root.right, p, q); + let curr = (root.data == p || root.data == q); + + if(curr + left + right >= 2){ + lca_ans = root.data; + } + return curr + left + right; +} + +let pre = [3,9,20,15,7]; +let ino = [9,3,15,20,7]; + +let treenode = buildTree(pre, ino, 0, pre.length-1); +// levelOrderLevelWise(treenode); + +lca(treenode, 9, 15); +console.log("lca-", lca_ans); + + + + diff --git a/Trees/Binary_Trees/maxPathSum.js b/Trees/Binary_Trees/maxPathSum.js new file mode 100644 index 00000000..c28b1a39 --- /dev/null +++ b/Trees/Binary_Trees/maxPathSum.js @@ -0,0 +1,22 @@ +//! O(n) time | O(logn) space + +//! Facebook +function maxPathSum(tree) { + const [_, maxSum] = findMaxSum(tree); + return maxSum; +} + +function findMaxSum(tree) { + if(!tree) return [-Infinity, -Infinity]; + + const [leftMaxSumAsBranch, leftMaxPathSum] = findMaxSum(tree.left); + const [rightMaxSumAsBranch, rightMaxPathSum] = findMaxSum(tree.right); + const maxChildSumAsBranch = Math.max(leftMaxSumAsBranch, rightMaxSumAsBranch); + + const {value} = tree.value; + const maxSumAsBranch = Math.max(maxChildSumAsBranch + value, value); + const maxSumAsRootNode = Math.max(leftMaxSumAsBranch + value + rightMaxSumAsBranch, maxSumAsBranch); + const maxPathSum = Math.max(leftMaxPathSum, rightMaxPathSum, maxSumAsRootNode); + + return [maxChildSumAsBranch, maxPathSum]; +} \ No newline at end of file diff --git a/Trees/Binary_Trees/nodeDepths.js b/Trees/Binary_Trees/nodeDepths.js new file mode 100644 index 00000000..86943a62 --- /dev/null +++ b/Trees/Binary_Trees/nodeDepths.js @@ -0,0 +1,36 @@ +//! O(n) time | O(d) space +function nodeDepths(root, depth = 0) { + + if(root === null) return 0; + + return depth + nodeDepths(root.left, depth + 1) + nodeDepths(root.right, depth + 1); +} + +//! O(n) time | O(d) space +function nodeDepths(root) { + + let sumOfDepths = 0; + + const stack = [{node: root, depth: 0}]; + + while(stack.length > 0) { + const {node, depth} = stack.pop(); + if(node === null) continue; + + sumOfDepths += depth; + + stack.push({node: node.left, depth: depth + 1}); + stack.push( {node: node.right, depth: depth + 1}); + } + return sumOfDepths; +} + + +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + diff --git a/Trees/Binary_Trees/nodeStructure.js b/Trees/Binary_Trees/nodeStructure.js new file mode 100644 index 00000000..ba67d748 --- /dev/null +++ b/Trees/Binary_Trees/nodeStructure.js @@ -0,0 +1,56 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +function findPath(root) { + + let leftPath = findLeftPath(root); + let rightPath = findRightPath(root); + + let result = []; + + result.push(leftPath); + result.push(rightPath); + + return result; + + } + +function findLeftPath(root) { + + findSum(root, 0); + +} + +function findRightPath(root) { + +if(root.left == null && root.right == null) return root.data; +return root.data + findRightPath(root.right); + +} + +function findSum(root, sum ) { + if(root.left == null && root.right == null) return; + +} + + + +const root = new Node(1); +root.left = new Node(2); +root.right = new Node(3); +root.left.left = new Node(4); +root.left.right = new Node(5); +root.left.left.left = new Node(8); +root.left.left.right = new Node(9); +root.right.left = new Node(6); +root.right.right = new Node(7); + + + diff --git a/Trees/Binary_Trees/printRightView.js b/Trees/Binary_Trees/printRightView.js new file mode 100644 index 00000000..8ae09ce0 --- /dev/null +++ b/Trees/Binary_Trees/printRightView.js @@ -0,0 +1,132 @@ +//! 14/02/2022 + +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } + +} + +class Queue { + constructor() { + this.data = []; + this.rear = 0; + this.front = 0; + } + + length() { + return this.rear - this.front; + } + + isEmpty() { + return this.length() == 0; + } + + enqueue(element) { + this.data[this.rear++] = element; + } + + dequeue() { + if(!this.isEmpty()) { + let temp = this.data[this.front++]; + return temp; + } + } + + getFront() { + if(!this.isEmpty()) { + return this.data[this.front]; + } + return undefined; + } +} + +function printRightViewAlgo1(root) { + + let queue = new Queue(); + let null_node = new Node(null); + queue.enqueue(root); + queue.enqueue(null_node); + let result = []; + while(!queue.isEmpty()) { + let current = queue.dequeue(); + if(current.data == null) { + console.log(result[result.length - 1]); + if(!queue.isEmpty()) { + queue.enqueue(new Node(null)); + result = []; + } + } else { + result.push(current.data); + } + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } +} + +function printRightViewAlgo2(root) { + //! removed result array + let queue = new Queue(); + let null_node = new Node(null); + queue.enqueue(root); + queue.enqueue(null_node); + let last_element = undefined; + + while(!queue.isEmpty()) { + let current = queue.dequeue(); + if(current.data == null) { + console.log(last_element); + if(!queue.isEmpty()) { + queue.enqueue(new Node(null)); + } + } else { + last_element = current.data; + } + if(current.left != null) { + queue.enqueue(current.left); + } + if(current.right != null) { + queue.enqueue(current.right); + } + } +} + +let maxLevelVisited = -1; +function printRightViewAlgo3(root, current) { + if(root == null) return; + + if(current > maxLevelVisited) { + console.log(root.data); + maxLevelVisited = current; + } + + printRightViewAlgo3(root.right, current + 1); + printRightViewAlgo3(root.left, current + 1); + + +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); + +root.left.left = new Node(40); +root.left.right = new Node(50); + +root.right.right = new Node(60); +root.right.right.right = new Node(70); + +// printRightViewAlgo1(root); + +// printRightViewAlgo2(root); + +printRightViewAlgo3(root, 0); + + + diff --git a/Trees/Binary_Trees/rightSiblingTree.js b/Trees/Binary_Trees/rightSiblingTree.js new file mode 100644 index 00000000..a3b2cab1 --- /dev/null +++ b/Trees/Binary_Trees/rightSiblingTree.js @@ -0,0 +1,32 @@ +class BinaryTree { + constructor(value) { + this.value = value; + this.left = null; + this.right = null; + } +} + +//! O(n) time | O(d) space where d is depth. +function rightSiblingTree(root) { + mutate(root, null, null); + return root; +} + +function mutate(node, parent, isLeftChild) { + if(!node) return; + + const left = node.left; + const right = node.right; + + mutate(left, parent, true); + + if(!parent) node.right = null; + else if(isLeftChild) node.right = parent.right; + else { + if(!parent.right) node.right = null; + else node.right = parent.right.left; + } + + mutate(right, parent, false); +} + diff --git a/Trees/Binary_Trees/tempCodeRunnerFile 2.js b/Trees/Binary_Trees/tempCodeRunnerFile 2.js new file mode 100644 index 00000000..6a54eb94 --- /dev/null +++ b/Trees/Binary_Trees/tempCodeRunnerFile 2.js @@ -0,0 +1 @@ +let temp = this.heap[idx]; \ No newline at end of file diff --git a/Trees/Binary_Trees/tempCodeRunnerFile.js b/Trees/Binary_Trees/tempCodeRunnerFile.js new file mode 100644 index 00000000..52cd99bf --- /dev/null +++ b/Trees/Binary_Trees/tempCodeRunnerFile.js @@ -0,0 +1,6 @@ +root.left.left = new Node(4); +root.left.right = new Node(5); +root.left.left.left = new Node(8); +root.left.left.right = new Node(9); +root.right.left = new Node(6); +root.right.right = new Node(7); \ No newline at end of file diff --git a/Trees/Binary_Trees/treeTraversal.js b/Trees/Binary_Trees/treeTraversal.js new file mode 100644 index 00000000..0a0f39ce --- /dev/null +++ b/Trees/Binary_Trees/treeTraversal.js @@ -0,0 +1,42 @@ +//!12/02/2022 +class Node { + constructor(data) { + this.data = data; + this.left = null; + this.right = null; + } +} + +function preOrder(root) { + if(root == null) return; + console.log(root.data); + preOrder(root.left); + preOrder(root.right); +} + +function inOrder(root) { + if (root == null) return; + inOrder(root.left); + console.log(root.data); + inOrder(root.right); +} + +function postOrder(root) { + if(root == null) return; + postOrder(root.left); + postOrder(root.right); + console.log(root.data); +} + +const root = new Node(10); +root.left = new Node(20); +root.right = new Node(30); +root.left.left = new Node(40); +root.left.root = new Node(50); +root.right.right = new Node(60); +root.right.right.right = new Node(70); +preOrder(root); +console.log(">>>>>>>>>"); +inOrder(root); +console.log(">>>>>>>>>"); +postOrder(root) \ No newline at end of file diff --git a/Tries/trie_implimentation.js b/Tries/trie_implimentation.js new file mode 100644 index 00000000..f2d4f6d2 --- /dev/null +++ b/Tries/trie_implimentation.js @@ -0,0 +1,72 @@ +class TrieNode { + constructor(value) { + this.data = value; + this.isEndOfWord = false; + this.children = new Map(); + } +} + +function insert(root, str) { + let temp = root; + for(let i = 0; i < str.length; i++) { + let data = str[i]; + if(temp.children.get(data)){ + temp = temp.children.get(data); + } else { + temp.children.set(data, new TrieNode(data)); + temp = temp.children.get(data); + } + } + temp.isEndOfWord = true; +} + +function search(root, str) { + let temp = root; + for(let i = 0; i < str.length; i++) { + let data = str[i]; + if(temp.children.get(data)){ + temp = temp.children.get(data); + } else { + return false; + } + } + return temp.isEndOfWord == true; +} + +function helper(root, pre, output) { + if(!root) return; + if(root.isEndOfWord) { + console.log(pre + output); + } + for(const [key, value] of root.children.entries()) { + helper(value, pre, output + key); + } + } + +function prefix_search(root, pre) { + let temp = root; + for(let i = 0; i < pre.length; i++) { + let data = pre[i]; + if(temp.children.get(data)) { + temp = temp.children.get(data); + } else { + console.log("Prefix not found"); + return; + } + } + helper(temp, pre, ""); +} + +let rootNode = new TrieNode('\0'); + +insert(rootNode, "bat"); +insert(rootNode, "batman"); +insert(rootNode, "super"); +insert(rootNode, "superman"); +insert(rootNode, "batgirl"); +insert(rootNode, "wonder"); +insert(rootNode, "woman"); + +// console.log(search(rootNode, "batgirl")); + +prefix_search(rootNode, "bat"); \ No newline at end of file diff --git a/sorting/.DS_Store b/sorting/.DS_Store new file mode 100644 index 00000000..4454d279 Binary files /dev/null and b/sorting/.DS_Store differ diff --git a/sorting/bubble_sort.js b/sorting/bubble_sort.js new file mode 100644 index 00000000..2402f2d4 --- /dev/null +++ b/sorting/bubble_sort.js @@ -0,0 +1,26 @@ +//! worst-case: O(n^2) time | O(1) space +//! avg-case: O(n^2) time | O(1) space +//! best-case: O(n) time | O(1) space + +function bubbleSort(array) { + let isSorted = false; + let counter = 0; + while(!isSorted) { + isSorted = true; + for(let i = 0; i < array.length - 1 - counter; i++) { + if(array[i] > array[i + 1]) { + swap(i, i + 1, array); + isSorted = false; + } + } + counter++; + } + return array; +} +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + + +let array = [8, -6, 7, 10, 8, -1, 6, 2, 4, -5, 1, 10, 8, -10, -9, -10, 8, 9, -2, 7, -2, 4]; +console.log(bubbleSort(array)); \ No newline at end of file diff --git a/sorting/bucketSort.js b/sorting/bucketSort.js new file mode 100644 index 00000000..273955f2 --- /dev/null +++ b/sorting/bucketSort.js @@ -0,0 +1,20 @@ +// ! O(n) time | O(1) | space modified bucket sort +function three_number_sort(array, order) { + const valueCounts = [0, 0, 0]; + for(const element of array) { + const orderIdx = order.indexOf(element); + valueCounts[orderIdx]++; + } + for(let idx = 0; idx < 3; idx++) { + const value = order[idx]; + const count = valueCounts[idx]; + + const numElementsBefore = valueCounts.slice(0, idx).reduce((a, b) => a + b, 0); + + for(let n = 0; n < count; n++) { + const currentIdx = numElementsBefore + n; + array[currentIdx] = value; + } + } + return array; +} \ No newline at end of file diff --git a/sorting/heapSort/continuous_median.js b/sorting/heapSort/continuous_median.js new file mode 100644 index 00000000..446dcb12 --- /dev/null +++ b/sorting/heapSort/continuous_median.js @@ -0,0 +1,116 @@ +class ContinuousMedianHandler { + constructor() { + this.lowers = new Heap(MAX_HEAP_FUNC, []); + this.greaters = new Heap(MIN_HEAP_FUNC, []); + this.median = null; + } + +//! O(logn) time | O(n) space + insert(number) { + if(!this.lowers.length || number < this.lowers.peek()){ + this.lowers.insert(number); + } else { + this.greaters.insert(number); + } + this.rebalanceHeaps(); + this.updateMedian(); + } + + rebalanceHeaps() { + if(this.lowers.length - this.greaters.length === 2) { + this.greaters.insert(this.lowers.remove()); + } else if(this.greaters.length - this.lowers.length === 2) { + this.lowers.insert(this.greaters.remove()); + } + } + updateMedian() { + if(this.lowers.length === this.greaters.length) { + this.median = (this.lowers.peek() + this.greaters.peek()) / 2; + } else if(this.lowers.length > this.greaters.length) { + this.median = this.lowers.peek(); + } else { + this.median = this.greaters.peek(); + } + } + getMedian() { + return this.median; + } +} +class Heap { + constructor(comparisonFunc, array) { + this.comparisonFunc = comparisonFunc; + this.heap = this.buildHeap(array); + this.length = this.heap.length; + } + + buildHeap(array) { + const firstParentIdx = Math.floor((array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx >= 0; currentIdx--) { + this.siftDown(currentIdx, array.length - 1, array); + } + return array; + } + siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(childOneIdx <= endIdx) { + const childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2 : -1; + let idxToSwap; + if(childTwoIdx !== -1) { + if(this.comparisonFunc(heap[childTwoIdx], heap[childOneIdx])) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + } else { + idxToSwap = childOneIdx; + } if(this.comparisonFunc(heap[idxToSwap], heap[currentIdx])) { + this.swap(currentIdx, idxToSwap, heap); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + } + } + siftUp(currentIdx, heap) { + let parentIdx = Math.floor((currentIdx - 1) / 2); + while(currentIdx > 0) { + if(this.comparisonFunc(heap[currentIdx], heap[parentIdx])) { + this.swap(currentIdx, parentIdx, heap); + currentIdx = parentIdx; + parentIdx = Math.floor((currentIdx - 1) / 2); + } else { + return; + } + } + } + + peek() { + return this.heap[0]; + } + + remove() { + this.swap(0, this.length - 1, this.heap); + const valueToRemove = this.heap.pop(); + this.length--; + this.siftDown(0, this.length - 1, this.heap); + return valueToRemove; + } + + insert(value) { + this.heap.push(value); + this.length++; + this.siftUp(this.length - 1, this.heap); + } + + swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; + } +} + +function MAX_HEAP_FUNC(a, b) { + return a > b; +} +function MIN_HEAP_FUNC(a, b) { + return a < b; +} \ No newline at end of file diff --git a/sorting/heapSort/heapsort.js b/sorting/heapSort/heapsort.js new file mode 100644 index 00000000..b6023a9b --- /dev/null +++ b/sorting/heapSort/heapsort.js @@ -0,0 +1,47 @@ +//! Best: O(nlogn) time | O(1) space +//! Best: O(nlogn) time | O(1) space +//! Worst: O(nlogn) time | O(1) space + +function heapSort(array) { + buildMaxHeap(array); + for(let endIdx = array.length - 1; endIdx > -1; endIdx--) { + swap(0, endIdx, array); + siftDown(0, endIdx - 1, array); + } + return array; +} + +function buildMaxHeap(array) { + let firstParentIdx = Math.floor((array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx > -1; currentIdx--) { + siftDown(currentIdx, array.length - 1, array); + } +} + +function siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(childOneIdx <= endIdx) { + let childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2 : -1; + let idxToSwap; + if(childTwoIdx != -1 && heap[childTwoIdx] > heap[childOneIdx]) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + if(heap[idxToSwap] > heap[currentIdx]) { + swap(idxToSwap, currentIdx, array); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + } +} + +function swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; +} + + +let array = [48, 12, 24, 7, 8, -5, 24, 391, 24, 56, 2, 6, 8, 41]; +console.log(heapSort(array)); \ No newline at end of file diff --git a/sorting/heapSort/minHeap.js b/sorting/heapSort/minHeap.js new file mode 100644 index 00000000..cb935407 --- /dev/null +++ b/sorting/heapSort/minHeap.js @@ -0,0 +1,65 @@ +class MinHeap { + constructor(array) { + this.heap = this.buildHeap(array); + } + //! O(n) time | O(1) space + buildHeap(array) { + const firstParentIdx = Math.floor((array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx > -1; currentIdx--) { + this.siftDown(currentIdx, array.length - 1, array); + } + } + //! O(logn) time | O(1) space + siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(currentIdx <= endIdx) { + const childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2: -1; + let idxToSwap; + if(childTwoIdx != -1 && heap[childTwoIdx] < heap[childOneIdx]) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + if(heap[idxToSwap] < heap[currentIdx]) { + this.swap(idxToSwap, currentIdx, heap); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + + }; + } + //! O(logn) time | O(1) space + siftUp(currentIdx, heap) { + let parentIdx = Math.floor( (currentIdx - 1) / 2 ); + while(currentIdx > 0 && heap[currentIdx] < heap[parentIdx]) { + this.swap(currentIdx, parentIdx, heap); + currentIdx = parentIdx; + parentIdx = Math.floor( (currentIdx - 1) / 2 ); + } + } + //! O(1) time | O(1) space + peek() { + return this.heap[0]; + } + //! O(logn) time | O(1) space + remove() { + this.swap(0, this.heap,length - 1, this.heap); + const valueToRemove = this.heap.pop(); + this.siftDown(0, this.heap.length - 1, this.heap); + return valueToRemove; + } + //! O(logn) time | O(1) space + insert(value) { + this.heap.push(value); + this.siftUp(this.heap.length - 1, this.heap); + } + //! O(1) time | O(1) space + swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; + } +} + +let array = [48, 12, 24, 7, 8, -5, 24, 391, 24, 56, 2, 6, 8, 41]; +const heap = new MinHeap(array); \ No newline at end of file diff --git a/sorting/heapSort/sort_ksorted_arrays.js b/sorting/heapSort/sort_ksorted_arrays.js new file mode 100644 index 00000000..b0a79505 --- /dev/null +++ b/sorting/heapSort/sort_ksorted_arrays.js @@ -0,0 +1,87 @@ +//! O(nlog(k)) time | O(k) space - where n is the number of elements +//! in the array and k is how far away elements are from their sorted position. + +function sortKSortedArray(array, k) { + + const minHeapWithElements = new MinHeap(array.slice(0, Math.min(k + 1, array.length))); + + let nextIndexToInsertElement = 0; + for(let idx = k + 1; idx < array.length; idx++) { + const minElement = minHeapWithElements.remove(); + array[nextIndexToInsertElement] = minElement; + nextIndexToInsertElement++; + + const currentElement = array[idx]; + minHeapWithElements.insert(currentElement); + } + while(!minHeapWithElements.isEmpty()) { + const minElement = minHeapWithElements.remove(); + array[nextIndexToInsertElement] = minElement; + nextIndexToInsertElement++; + } + + return array; + } +class MinHeap { + constructor(array) { + this.heap = this.buildHeap(array); + } + isEmpty() { + return this.heap.length === 0; + } + buildHeap(array) { + const firstParentIdx = Math.floor( (array.length - 2) / 2); + for(let currentIdx = firstParentIdx; currentIdx >= 0; currentIdx--) { + this.siftDown(currentIdx, array.length - 1, array); + } + return array; + } + siftDown(currentIdx, endIdx, heap) { + let childOneIdx = currentIdx * 2 + 1; + while(childOneIdx <= endIdx) { + const childTwoIdx = currentIdx * 2 + 2 <= endIdx ? currentIdx * 2 + 2 : -1; + let idxToSwap; + if(childTwoIdx !== -1 && heap[childTwoIdx] < heap[childOneIdx]) { + idxToSwap = childTwoIdx; + } else { + idxToSwap = childOneIdx; + } + if(heap[idxToSwap] < heap[currentIdx]) { + this.swap(currentIdx, idxToSwap, heap); + currentIdx = idxToSwap; + childOneIdx = currentIdx * 2 + 1; + } else { + return; + } + } + } + + siftUp(currentIdx, heap) { + let parentIdx = Math.floor((currentIdx - 1) / 2); + while(currentIdx > 0 && heap[currentIdx] < heap[parentIdx]) { + this.swap(currentIdx, parentIdx, heap); + currentIdx = parentIdx; + parentIdx = Math.floor( (currentIdx - 1) / 2); + } + } + peek() { + return this.heap[0]; + } + remove() { + this.swap(0, this.heap.length - 1, this.heap); + const valueToRemove = this.heap.pop(); + this.siftDown(0, this.heap.length - 1, this.heap); + return valueToRemove; + } + insert(value) { + this.heap.push(value); + this.siftUp(this.heap.length - 1, this.heap); + } + swap(i, j, heap) { + [ heap[i], heap[j] ] = [ heap[j], heap[i] ]; + } +} + +let arr = [3, 2, 1, 5, 4, 7, 6, 5]; +let k = 3; +console.log(sortKSortedArray(arr, k)); \ No newline at end of file diff --git a/sorting/insertion_sort.js b/sorting/insertion_sort.js new file mode 100644 index 00000000..3acb2908 --- /dev/null +++ b/sorting/insertion_sort.js @@ -0,0 +1,23 @@ +//! worst-case: O(n^2) time | O(1) space +//! avg-case: O(n^2) time | O(1) space +//! best-case: O(n) time | O(1) space + +function insertionSort(array) { + for(let i = 1; i < array.length; i++) { + let j = i; + while( j > 0 && array[j] < array[j - 1] ) { + swap(j, j - 1, array); + j -= 1; + } + } + return array; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +let array = [8, -6, 7, 10, 8, -1, 6, 2, 4, -5, 1, 10, 8, -10, -9, -10, 8, 9, -2, 7, -2, 4]; + +console.log(insertionSort(array)); + \ No newline at end of file diff --git a/sorting/mergeSort/countInversions.js b/sorting/mergeSort/countInversions.js new file mode 100644 index 00000000..a8d6df10 --- /dev/null +++ b/sorting/mergeSort/countInversions.js @@ -0,0 +1,52 @@ +function countInversions(array) { + return countInversionsHelper(array, 0, array.length - 1); +} +function countInversionsHelper(array, startIdx, endIdx) { + if(startIdx >= endIdx) return 0; + let midIdx = Math.floor((startIdx + endIdx) / 2); + let leftInversions = countInversionsHelper(array, startIdx, midIdx); + let rightInversions = countInversionsHelper(array, midIdx + 1, endIdx); + let mergedInversions = mergeAndCountInversions(array, startIdx, midIdx, midIdx + 1, endIdx); + return leftInversions + rightInversions + mergedInversions; +} +function mergeAndCountInversions(array, leftStartIdx, leftEndIdx, rightStartIdx, rightEndIdx) { + let inversions = 0; + let leftArrLength = leftEndIdx - leftStartIdx + 1; + let rightArrLength = rightEndIdx - rightStartIdx + 1; + + let arr1 = new Array(leftArrLength); + let arr2 = new Array(rightArrLength); + + for(let i = 0; i < leftArrLength; i++) { + arr1[i] = array[leftStartIdx + i]; + } + for(let i = 0; i < rightArrLength; i++) { + arr2[i] = array[rightStartIdx + i]; + } + + let i = 0; + let j = 0; + let k = leftStartIdx; + + while(i < leftArrLength && j < rightArrLength) { + if(arr1[i] <= arr2[j]) { + array[k++] = arr1[i++]; + }else { + inversions += leftArrLength - i; + array[k++] = arr2[j++]; + } + } + + while(i < leftArrLength) { + array[k++] = arr1[i++]; + } + while(j < rightArrLength) { + array[k++] = arr2[j++]; + } + + return inversions; +} + +let array = [2, 3, 3, 1, 9, 5, 6]; + +console.log(countInversions(array)); diff --git a/sorting/mergeSort/mergeSort.js b/sorting/mergeSort/mergeSort.js new file mode 100644 index 00000000..919ef2b4 --- /dev/null +++ b/sorting/mergeSort/mergeSort.js @@ -0,0 +1,45 @@ +//! every case O(nlogn) time | O(n) space + +function mergeSort(array) { + mergeSortHelper(array, 0, array.length - 1); + return array; +} +function mergeSortHelper(array, startIdx, endIdx) { + if (startIdx == endIdx) return; + const midIdx = Math.floor(startIdx + (endIdx - startIdx) / 2); + mergeSortHelper(array, startIdx, midIdx); + mergeSortHelper(array, midIdx + 1, endIdx); + doMerge(array, startIdx, midIdx, midIdx + 1, endIdx); +} +function doMerge(array, leftStartIdx, leftEndIdx, rightStartIdx, rightEndIdx) { + let leftSubArrLen = leftEndIdx - leftStartIdx + 1; + let rightSubArrLen = rightEndIdx - rightStartIdx + 1; + + let leftSubArr = new Array(leftSubArrLen); + let rightSubArr = new Array(rightSubArrLen); + + for (let i = 0; i < leftSubArrLen; i++) + leftSubArr[i] = array[leftStartIdx + i]; + + for (let i = 0; i < rightSubArrLen; i++) + rightSubArr[i] = array[rightStartIdx + i]; + + let i = 0; + let j = 0; + let k = leftStartIdx; + + while (i < leftSubArrLen && j < rightSubArrLen) { + if (leftSubArr[i] < rightSubArr[j]) array[k++] = leftSubArr[i++]; + else array[k++] = rightSubArr[j++]; + } + while (i < leftSubArrLen) array[k++] = leftSubArr[i++]; + while (j < rightSubArrLen) array[k++] = rightSubArr[j++]; + return; +} + +let array = [ + 2, -2, -6, -10, 10, 4, -8, -1, -8, -4, 7, -4, 0, 9, -9, 0, -9, -9, 8, 1, -4, + 4, 8, 5, 1, 5, 0, 0, 2, -10, +]; + +console.log(mergeSort(array)); diff --git a/sorting/quickSort/modified_quick_sort.js b/sorting/quickSort/modified_quick_sort.js new file mode 100644 index 00000000..769ea9e9 --- /dev/null +++ b/sorting/quickSort/modified_quick_sort.js @@ -0,0 +1,45 @@ + +//! best/avg case O(nlogn) time | O(logn) space +//! worst case O(n^2) time | O(logn) space +//! inplace algorithm +function quickSort(array) { + quickSortHelper(array, 0, array.length - 1); + return array; +} + +function quickSortHelper(array, startIdx, endIdx) { + while(startIdx <= endIdx) { + if(startIdx == endIdx) return array[startIdx]; + else { + let m = partition(array, startIdx, endIdx); + if((m - startIdx) < (endIdx - m)) { + quickSortHelper(array, startIdx, m - 1); + startIdx = m + 1; + } else { + quickSortHelper(array, m + 1, endIdx); + endIdx = m - 1; + } + } + } +} + +function partition(array, leftIdx, rightIdx) { + let i = leftIdx; + let pivot = array[i]; + for(let j = i + 1; j <= rightIdx; j++) { + if(array[j] < pivot) { + i++; + swap(i, j, array); + } + } + swap(leftIdx, i, array); + return i; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +const array = [8, 5, 2, 9, 5, 6, 3]; + +console.log(quickSort(array)); \ No newline at end of file diff --git a/sorting/quickSort/quick_sort.js b/sorting/quickSort/quick_sort.js new file mode 100644 index 00000000..6e4915d8 --- /dev/null +++ b/sorting/quickSort/quick_sort.js @@ -0,0 +1,38 @@ + +//! best/avg case O(nlogn) time | O(logn) space +//! worst case O(n^2) time | O(n) space + +function quickSort(array) { + quickSortHelper(array, 0, array.length - 1); + return array; +} + +function quickSortHelper(array, startIdx, endIdx) { + if(startIdx >= endIdx) return; + else { + let m = partition(array, startIdx, endIdx); + quickSortHelper(array, startIdx, m - 1); + quickSortHelper(array, m + 1, endIdx); + } +} + +function partition(array, leftIdx, rightIdx) { + let i = leftIdx; + let pivot = array[i]; + for(let j = i + 1; j <= rightIdx; j++) { + if(array[j] < pivot) { + i++; + swap(i, j, array); + } + } + swap(leftIdx, i, array); + return i; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +const array = [8, 5, 2, 9, 5, 6, 3]; + +console.log(quickSort(array)); \ No newline at end of file diff --git a/sorting/selection_sort.js b/sorting/selection_sort.js new file mode 100644 index 00000000..d9806c24 --- /dev/null +++ b/sorting/selection_sort.js @@ -0,0 +1,23 @@ +//! worst-case: O(n^2) time | O(1) space +//! avg-case: O(n^2) time | O(1) space +//! best-case: O(n^2) time | O(1) space + +function selectionSort(array) { + let startIdx = 0; + while(startIdx < array.length - 1) { + let smallestIdx = startIdx; + for(let i = startIdx + 1; i < array.length; i++) { + if(array[smallestIdx] > array[i]) smallestIdx = i; + } + swap(startIdx, smallestIdx, array); + startIdx++; + } + return array; +} + +function swap(i, j, array) { + [array[i], array[j]] = [array[j], array[i]]; +} + +let array = [8, -6, 7, 10, 8, -1, 6, 2, 4, -5, 1, 10, 8, -10, -9, -10, 8, 9, -2, 7, -2, 4]; +console.log(selectionSort(array)); \ No newline at end of file