diff --git a/Backtracking/NQueens.js b/Backtracking/NQueens.js index 307c66dc04..18daad5611 100644 --- a/Backtracking/NQueens.js +++ b/Backtracking/NQueens.js @@ -1,8 +1,9 @@ class NQueens { constructor(size) { - if (size < 0) { - throw RangeError('Invalid board size') + if (size <= 0) { + throw RangeError('Board size must be a positive integer') } + this.board = new Array(size).fill('.').map(() => new Array(size).fill('.')) this.size = size this.solutionCount = 0 @@ -40,7 +41,7 @@ class NQueens { solve(col = 0) { if (col >= this.size) { this.solutionCount++ - return true + return } for (let i = 0; i < this.size; i++) { @@ -50,8 +51,6 @@ class NQueens { this.removeQueen(i, col) } } - - return false } printBoard(output = (value) => console.log(value)) { diff --git a/Search/BinarySearch.js b/Search/BinarySearch.js index c5477cb7b9..475718129c 100644 --- a/Search/BinarySearch.js +++ b/Search/BinarySearch.js @@ -8,44 +8,46 @@ */ function binarySearchRecursive(arr, x, low = 0, high = arr.length - 1) { + if (!Array.isArray(arr) || arr.length === 0) { + return -1 + } + const mid = Math.floor(low + (high - low) / 2) if (high >= low) { if (arr[mid] === x) { - // item found => return its index return mid } if (x < arr[mid]) { - // arr[mid] is an upper bound for x, so if x is in arr => low <= x < mid return binarySearchRecursive(arr, x, low, mid - 1) } else { - // arr[mid] is a lower bound for x, so if x is in arr => mid < x <= high return binarySearchRecursive(arr, x, mid + 1, high) } - } else { - // if low > high => we have searched the whole array without finding the item - return -1 } + + return -1 } + function binarySearchIterative(arr, x, low = 0, high = arr.length - 1) { + if (!Array.isArray(arr) || arr.length === 0) { + return -1 + } + while (high >= low) { const mid = Math.floor(low + (high - low) / 2) if (arr[mid] === x) { - // item found => return its index return mid } if (x < arr[mid]) { - // arr[mid] is an upper bound for x, so if x is in arr => low <= x < mid high = mid - 1 } else { - // arr[mid] is a lower bound for x, so if x is in arr => mid < x <= high low = mid + 1 } } - // if low > high => we have searched the whole array without finding the item + return -1 } diff --git a/Sliding-Windows/LongestSubarrayWithSumAtMost.js b/Sliding-Windows/LongestSubarrayWithSumAtMost.js index b970539ee0..7576ebec6c 100644 --- a/Sliding-Windows/LongestSubarrayWithSumAtMost.js +++ b/Sliding-Windows/LongestSubarrayWithSumAtMost.js @@ -6,16 +6,32 @@ * @returns {number} - The length of the longest subarray with a sum <= target. */ export function longestSubarrayWithSumAtMost(arr, target) { + if (!Array.isArray(arr)) { + throw new TypeError('First argument must be an array') + } + + if (typeof target !== 'number') { + throw new TypeError('Target must be a number') + } + + if (arr.length === 0) { + return 0 + } + let maxLength = 0 let windowSum = 0 let left = 0 + for (let right = 0; right < arr.length; right++) { windowSum += arr[right] + while (windowSum > target) { windowSum -= arr[left] left++ } + maxLength = Math.max(maxLength, right - left + 1) } + return maxLength } diff --git a/Sorts/BubbleSort.js b/Sorts/BubbleSort.js index 5571fac047..6522aa2811 100644 --- a/Sorts/BubbleSort.js +++ b/Sorts/BubbleSort.js @@ -1,33 +1,30 @@ /* Bubble Sort is an algorithm to sort an array. It - * compares adjacent element and swaps their position - * The big O on bubble sort in worst and best case is O(N^2). - * Not efficient. - * Somehow if the array is sorted or nearly sorted then we can optimize bubble sort by adding a flag. + * compares adjacent elements and swaps their position. + * The big O on bubble sort in worst and best case is O(N^2). * - * In bubble sort, we keep iterating while something was swapped in - * the previous inner-loop iteration. By swapped I mean, in the - * inner loop iteration, we check each number if the number proceeding - * it is greater than itself, if so we swap them. - * - * Wikipedia: https://en.wikipedia.org/wiki/Bubble_sort - * Animated Visual: https://www.toptal.com/developers/sorting-algorithms/bubble-sort + * Wikipedia: https://en.wikipedia.org/wiki/Bubble_sort */ /** * Using 2 for loops. */ -export function bubbleSort(items) { +export function bubbleSort(list) { + if (!Array.isArray(list)) { + throw new TypeError('Given input is not an array') + } + + if (list.length === 0) { + return [] + } + + const items = [...list] const length = items.length let noSwaps for (let i = length; i > 0; i--) { - // flag for optimization noSwaps = true - // Number of passes for (let j = 0; j < i - 1; j++) { - // Compare the adjacent positions if (items[j] > items[j + 1]) { - // Swap the numbers ;[items[j], items[j + 1]] = [items[j + 1], items[j]] noSwaps = false } @@ -43,7 +40,16 @@ export function bubbleSort(items) { /** * Using a while loop and a for loop. */ -export function alternativeBubbleSort(arr) { +export function alternativeBubbleSort(list) { + if (!Array.isArray(list)) { + throw new TypeError('Given input is not an array') + } + + if (list.length === 0) { + return [] + } + + const arr = [...list] let swapped = true while (swapped) { diff --git a/Sorts/QuickSort.js b/Sorts/QuickSort.js index 3885054e36..c76adb6dcd 100644 --- a/Sorts/QuickSort.js +++ b/Sorts/QuickSort.js @@ -1,30 +1,28 @@ /** - * @function QuickSort - * @description Quick sort is a comparison sorting algorithm that uses a divide and conquer strategy. - * @param {Integer[]} items - Array of integers - * @return {Integer[]} - Sorted array. - * @see [QuickSort](https://en.wikipedia.org/wiki/Quicksort) + * @function quickSort + * @description Quick Sort is a divide-and-conquer comparison-based sorting algorithm. + * @param {number[]} items - Array of integers + * @returns {number[]} - Sorted array + * @timecomplexity Average: O(n log n), Worst: O(n²) + * @spacecomplexity O(n) + * @see https://en.wikipedia.org/wiki/Quicksort */ function quickSort(items) { - const length = items.length + if (items.length <= 1) return items - if (length <= 1) { - return items - } - const PIVOT = items[0] - const GREATER = [] - const LESSER = [] + const pivotIndex = Math.floor(items.length / 2) + const pivot = items[pivotIndex] + + const lesser = [] + const greater = [] - for (let i = 1; i < length; i++) { - if (items[i] > PIVOT) { - GREATER.push(items[i]) - } else { - LESSER.push(items[i]) - } + for (let i = 0; i < items.length; i++) { + if (i === pivotIndex) continue + if (items[i] < pivot) lesser.push(items[i]) + else greater.push(items[i]) } - const sorted = [...quickSort(LESSER), PIVOT, ...quickSort(GREATER)] - return sorted + return [...quickSort(lesser), pivot, ...quickSort(greater)] } export { quickSort } diff --git a/Sorts/SelectionSort.js b/Sorts/SelectionSort.js index 4e183be59a..b2b8f5749b 100644 --- a/Sorts/SelectionSort.js +++ b/Sorts/SelectionSort.js @@ -12,7 +12,13 @@ export const selectionSort = (list) => { if (!Array.isArray(list)) { throw new TypeError('Given input is not an array') } - const items = [...list] // We don't want to modify the original array + + if (list.length === 0) { + return [] + } + + const items = [...list] + const length = items.length for (let i = 0; i < length - 1; i++) { if (typeof items[i] !== 'number') {