Solving Problems with JavaScript - mchaitanya/algorithms_practice GitHub Wiki

Solving Problems with JavaScript

Standard built-in objects

  • -Infinity/+Infinity - can be useful to initialize a min/max variable
    Note: Number.MIN_VALUE is the number closest to 0, not the most negative number, that JavaScript can represent.
  • Math
    • Math.min / Math.max
    • Math.abs / Math.sign
    • Math.random - returns a pseudorandom number between 0 and 1
  • BigInt - special numeric type that provides support for integers of arbitrary length
  • Number
    • parseInt(string, [radix]) - to convert a numeric string to number
    • toString([radix]) - to convert a number of a string, where 2 <= radix <= 36
  • Date
    • new Date(year, monthIndex, day) // monthIndex is zero-based
    • Date.prototype.getDay // return day of the week (0-6)
  • Array
    • use as a stack with push() & pop()
    • use as a queue with push() & shift()
    • Array(arrayLength) - can be useful if we know how big the array will be, better than starting empty and pushing

    this implies an array of arrayLength empty slots, not slots with actual undefined values [calling say map on the result of Array(arrayLength) doesn't do anything, fill it first with 0]

    • Be careful with Array.prototype.fill - if you give it an object, each slot in the array will reference that object
    • sort an array in place with arr.sort([compareFn]) - calling arr.sort() on an array of numbers may not produce the right result

    The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.

  • String
    • String.prototype.charCodeAt(index) // maps a character to its UTF-16 code
    • String.fromCharCode(number) // converts UTF-16 code back to character, also note this is a 'class method'
    • String.prototype.padStart(targetLength [, padString]) // can be useful when working with numbers as strings etc.
    • String.prototype.localeCompare(compareString) - useful when sorting an array of strings
    • regexp.test(str) - ex: /[0-9a-z]/.test(char) to check if a char is alphanumeric
  • Map, API reference:
    • Map()
    • can initialize a map with Map(['key1', 'value1'], ['key2', 'value2'](/mchaitanya/algorithms_practice/wiki/'key1',-'value1'],-['key2',-'value2'))
    • Map.prototype.size
    • Map.prototype.has(key)
    • Map.prototype.get(key)
    • Map.prototype.set(key, value)
    • Map.prototype.delete(key)
    • iterate over a map with Map.prototype.keys(), Map.prototype.values(), Map.prototype.entries() - iterates its elements in insertion order
  • Set
    • Set()
    • can initialize a set with Set(array);
    • Set.prototype.size
    • Set.prototype.has(value)
    • Set.prototype.add(value)
    • Set.prototype.delete(value)
  • Heap - not available in the language, check implementation in the lib folder

Helpful syntax

// say, n1 & n2 are linked-list nodes
while (n1 != null || n2 != null) {
  // instead of `val1 = (n1 == null ? 100 : n1.val)`
  // use the nullish coalescing operator, otherwise you might end up with the default if val is 0
  let val1 = n1?.val ?? 100; 
  let val2 = n2?.val ?? 100; 

  // ...

  n1 = n1?.next;
  n2 = n2?.next;
}
let arr = [1, 2, 3, 4];
[arr[0], arr[1]] = [arr[1], arr[0]]; // swap 0th & 1st elements
  • Use default values for function arguments
  • Write a quick IIFE to do any recursive processing, example:
(function dfs(node, depth = 0) {
  if (node != null) {
    dfs(node.left, depth+1);
    dfs(node.right, depth+1);
  }
})(root);

all keys in the square bracket notation are converted to string unless they're Symbols

const seen = {};
seen[0,0](/mchaitanya/algorithms_practice/wiki/0,0) = true; // to keep track of seen cells in a grid, say
bfs:
while (level.length > 0) {
  for (let [r,c] of level) {
    if (r === rt && c === ct) break bfs;
  }
}
  • Use a generator to traverse/scan the solution space. They're also useful in modularizing the code - decoupling how values are produced from how they are processed.
function *getPrimes() {
  const seen = [];
  search:
  for (let num = 2; ; num++) {
    for (let prime of seen) {
      if (num % prime === 0) {
        continue search;
      }
    }
    seen.push(num);
    yield num;
  } 
}

Console API

  • When doing DFS on a tree, wrap each recursive call with a console.group(node.val) & console.groupEnd() to visualize the tree.
  • Use console.table(grid) to visualize the state of a 2-d grid.