The Coding Interview Bootcamp: Data structure and algorithm.
Part 1 String Reverse 1 2 3 function reverse (str ) { return str.split ('' ).reduce ((rev, char ) => char + rev, '' ); }
Paldinromes 1 2 3 4 5 function palindrome (str ) { return str.split ('' ).every ((char, i ) => { return char === str[str.length - i - 1 ]; }); }
another way is based on recursive method:
1 2 3 4 5 6 7 8 9 10 11 function palindromeRecursive (str ) { if (str.length <= 1 ) { return true ; } else { if (str[0 ] !== str[str.length - 1 ]) { return false ; } else { return palindromeRecursive (str.substring (1 , str.length - 1 )) } } }
Longest Paldinromes substring 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 function longestPalin (str ) { str = treatStr (str); console .log (str) let max = 0 ; for (let i = 1 ; i < str.length - 1 ; i++) { let radius = Math .min (i, str.length - i - 1 ); console .log (radius) let currentMax = getMaxSubLength (str, i, radius); if (max < currentMax) { max = currentMax + 1 ; } } return max; } function getMaxSubLength (str, i, radius ) { let max = 0 ; for (let j = 0 ; j <= radius; j++) { if (str[i - j] === str[i + j]) { max = j; } else { break ; } } return max; } function treatStr (str ) { let rtn = '' ; for (let i = 0 ; i < str.length ; i++) { if (i === str.length - 1 ) { rtn = rtn + str[i]; } else { rtn = rtn + str[i] + '#' ; } } return rtn; }
Integer Reversal 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 function reverseInt (n ) { const reversed = n .toString () .split ('' ) .reverse () .join ('' ); return parseInt (reversed) * Math .sign (n); }
Anagrams method1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function anagrams (stringA, stringB ) { const aCharMap = buildCharMap (stringA); const bCharMap = buildCharMap (stringB); if (Object .keys (aCharMap).length !== Object .keys (bCharMap).length ) { return false ; } for (let char in aCharMap) { if (aCharMap[char] !== bCharMap[char]) { return false ; } } return true ; } function buildCharMap (str ) { const charMap = {}; for (let char of str.replace (/[^\w]/g , '' ).toLowerCase ()) { charMap[char] = charMap[char] + 1 || 1 ; } return charMap; }
method2
1 2 3 4 5 6 7 8 9 10 11 12 function anagrams (stringA, stringB ) { return cleanString (stringA) === cleanString (stringB); } function cleanString (str ) { return str .replace (/[^\w]/g , '' ) .toLowerCase () .split ('' ) .sort () .join ('' ); }
Printing Steps The effect we need is as following:
1 2 3 4 5 6 7 8 9 10 11 12 13 --- Examples steps(2) '# ' '##' steps(3) '# ' '## ' '###' steps(4) '# ' '## ' '### ' '####'
solution based on recursive methods
1 2 3 4 5 6 7 8 9 10 11 12 13 function steps (n, row = 0 , stair = '' ) { if (n === row) { return ; } if (n === stair.length ) { console .log (stair); return steps (n, row + 1 ); } const add = stair.length <= row ? '#' : ' ' ; steps (n, row, stair + add); }
Enter the Matrix Spiral The requirement goes as following:
1 2 3 4 5 6 7 8 9 10 11 12 13 --- Examples matrix(2) [[undefined, undefined], [undefined, undefined]] matrix(3) [[1, 2, 3], [8, 9, 4], [7, 6, 5]] matrix(4) [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]]
solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 function matrix (n ) { const results = []; for (let i = 0 ; i < n; i++) { results.push ([]); } let counter = 1 ; let startColumn = 0 ; let endColumn = n - 1 ; let startRow = 0 ; let endRow = n - 1 ; while (startColumn <= endColumn && startRow <= endRow) { for (let i = startColumn; i <= endColumn; i++) { results[startRow][i] = counter; counter++; } startRow++; for (let i = startRow; i <= endRow; i++) { results[i][endColumn] = counter; counter++; } endColumn--; for (let i = endColumn; i >= startColumn; i--) { results[endRow][i] = counter; counter++; } endRow--; for (let i = endRow; i >= startRow; i--) { results[i][startColumn] = counter; counter++; } startColumn++; } return results; }
Fibonacci solution based on memoization and recursive .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function memoize (fn ) { const cache = {}; return function (...args ) { if (cache[args]) { return cache[args]; } const result = fn.apply (this , args); cache[args] = result; return result; }; } function slowFib (n ) { if (n < 2 ) { return n; } return fib (n - 1 ) + fib (n - 2 ); } const fib = memoize (slowFib);
The most simplified method goes as following:
1 2 3 4 5 6 7 8 9 10 11 12 function memoize (fn ) { const cache = {}; return function (n ) { if (cache[n]) { return cache[n]; } const result = fn (n); cache[n] = result; return result; } }
Make it more abstract like below:
1 2 3 4 5 6 7 8 9 10 11 12 13 function memoize (fn ) { const cache = {}; return function (...args ) { if (cache[args]) { return cache[args]; } const result = fn.apply (this , args); cache[args] = result; return result; }; }
Queue and Stack 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class Queue { constructor ( ) { this .data = []; } add (record ) { this .data .unshift (record); } remove ( ) { return this .data .pop (); } } class Stack { constructor ( ) { this .data = []; } push (record ) { this .data .push (record); } pop ( ) { return this .data .pop (); } peek ( ) { return this .data [this .data .length - 1 ]; } }
Two Become One Implement a Queue data structure using two stacks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const Stack = require ('./stack' );class Queue { constructor ( ) { this .first = new Stack (); this .second = new Stack (); } add (record ) { this .first .push (record); } remove ( ) { while (this .first .peek ()) { this .second .push (this .first .pop ()); } const record = this .second .pop (); while (this .second .peek ()) { this .first .push (this .second .pop ()); } return record; } peek ( ) { while (this .first .peek ()) { this .second .push (this .first .pop ()); } const record = this .second .peek (); while (this .second .peek ()) { this .first .push (this .second .pop ()); } return record; } }
Linked List 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 class Node { constructor (data, next = null ) { this .data = data; this .next = next; } } class LinkedList { constructor ( ) { this .head = null ; } insertFirst (data ) { this .head = new Node (data, this .head ); } size ( ) { let counter = 0 ; let node = this .head ; while (node) { counter++; node = node.next ; } return counter; } getFirst ( ) { return this .head ; } getLast ( ) { if (!this .head ) { return null ; } let node = this .head ; while (node) { if (!node.next ) { return node; } node = node.next ; } } clear ( ) { this .head = null ; } removeFirst ( ) { if (!this .head ) { return ; } this .head = this .head .next ; } removeLast ( ) { if (!this .head ) { return ; } if (!this .head .next ) { this .head = null ; return ; } let previous = this .head ; let node = this .head .next ; while (node.next ) { previous = node; node = node.next ; } previous.next = null ; } insertLast (data ) { const last = this .getLast (); if (last) { last.next = new Node (data); } else { this .head = new Node (data); } } getAt (index ) { let counter = 0 ; let node = this .head ; while (node) { if (counter === index) { return node; } counter++; node = node.next ; } return null ; } removeAt (index ) { if (!this .head ) { return ; } if (index === 0 ) { this .head = this .head .next ; return ; } const previous = this .getAt (index - 1 ); if (!previous || !previous.next ) { return ; } previous.next = previous.next .next ; } insertAt (data, index ) { if (!this .head ) { this .head = new Node (data); return ; } if (index === 0 ) { this .head = new Node (data, this .head ); return ; } const previous = this .getAt (index - 1 ) || this .getLast (); const node = new Node (data, previous.next ); previous.next = node; } forEach (fn ) { let node = this .head ; let counter = 0 ; while (node) { fn (node, counter); node = node.next ; counter++; } } *[Symbol .iterator ]() { let node = this .head ; while (node) { yield node; node = node.next ; } } }
Find the midpoint of linked list 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 --- Directions Return the 'middle' node of a linked list.If the list has an even number of elements, return the node at the end of the first half of the list. *Do not* use a counter variable, *do not* retrieve the size of the list, and only iterate through the list one time. --- Example const l = new LinkedList (); l.insertLast ('a' ) l.insertLast ('b' ) l.insertLast ('c' ) midpoint (l); function midpoint (list ) { let slow = list.getFirst (); let fast = list.getFirst (); while (fast.next && fast.next .next ) { slow = slow.next ; fast = fast.next .next ; } return slow; }
Multiply two Big numbers 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 function addbyStr (str1, str2 ) { let len = Math .max (str1.length , str2.length ); let increase = 0 ; let rtn = '' ; for (let i = 0 ; i < len; i++) { let ope1 = i <= str1.length - 1 ? str1[str1.length - 1 -i] : '0' ; let ope2 = i <= str2.length - 1 ? str2[str2.length - 1 -i] : '0' ; let temp = parseInt (ope1) + parseInt (ope2) + increase; if (temp >= 10 ) { increase = 1 ; temp = temp - 10 ; } else { increase = 0 ; } rtn = temp + rtn; } return rtn; } function addArr (arr ) { let result = arr.reduce ((rtn, each ) => { return rtn = addbyStr (rtn, each); }); return result; } function mutliTwoStr (str1, str2 ) { let rtn = []; for (let i = 0 ; i < str2.length ; i++) { let count = parseInt (str2[str2.length - 1 - i]); let temp = new Array (count).fill (str1) let tempResult = addArr (temp) tempResult = tempResult + '0' .repeat (i) rtn.push (tempResult) } return addArr (rtn); }