{"id":27731025,"url":"https://github.com/chesterheng/master-coding-interview","last_synced_at":"2025-04-28T07:01:52.793Z","repository":{"id":49308076,"uuid":"266679152","full_name":"chesterheng/master-coding-interview","owner":"chesterheng","description":"Master the Coding Interview: Data Structures + Algorithms","archived":false,"fork":false,"pushed_at":"2020-06-08T00:10:41.000Z","size":1601,"stargazers_count":209,"open_issues_count":1,"forks_count":89,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-04-16T10:23:01.981Z","etag":null,"topics":["javascript"],"latest_commit_sha":null,"homepage":"https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chesterheng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-25T04:01:08.000Z","updated_at":"2024-04-16T03:46:18.000Z","dependencies_parsed_at":"2022-08-29T17:02:16.649Z","dependency_job_id":null,"html_url":"https://github.com/chesterheng/master-coding-interview","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chesterheng%2Fmaster-coding-interview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chesterheng%2Fmaster-coding-interview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chesterheng%2Fmaster-coding-interview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chesterheng%2Fmaster-coding-interview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chesterheng","download_url":"https://codeload.github.com/chesterheng/master-coding-interview/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251267691,"owners_count":21561910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript"],"created_at":"2025-04-28T07:01:50.314Z","updated_at":"2025-04-28T07:01:52.777Z","avatar_url":"https://github.com/chesterheng.png","language":null,"readme":"# Master the Coding Interview: Data Structures + Algorithms\n\n## Table of contents\n\n- [Master the Coding Interview: Data Structures + Algorithms](#master-the-coding-interview-data-structures--algorithms)\n  - [Table of contents](#table-of-contents)\n  - [**Section 1: Introduction**](#section-1-introduction)\n  - [**Section 2: Getting More Interviews**](#section-2-getting-more-interviews)\n    - [Resume](#resume)\n    - [What If I Don't Have Enough Experience?](#what-if-i-dont-have-enough-experience)\n    - [Portfolio](#portfolio)\n    - [Where To Find Jobs?](#where-to-find-jobs)\n  - [**Section 3: Big O**](#section-3-big-o)\n    - [Setting Up Your Environment](#setting-up-your-environment)\n    - [What Is Good Code?](#what-is-good-code)\n    - [O(n)](#on)\n    - [O(1)](#o1)\n    - [Exercise: Big O Calculation](#exercise-big-o-calculation)\n    - [Exercise: Big O Calculation 2](#exercise-big-o-calculation-2)\n    - [Simplifying Big O](#simplifying-big-o)\n    - [Big O Rule 1 - Worst Case](#big-o-rule-1---worst-case)\n    - [Big O Rule 2 - Remove Constants](#big-o-rule-2---remove-constants)\n    - [Big O Rule 3 - Different terms for inputs](#big-o-rule-3---different-terms-for-inputs)\n    - [O(n^2)](#on2)\n    - [Big O Rule 4 - Drop Non Dominants](#big-o-rule-4---drop-non-dominants)\n    - [What Does This All Mean?](#what-does-this-all-mean)\n    - [O(n!)](#on-1)\n    - [3 Pillars Of Programming](#3-pillars-of-programming)\n    - [Space Complexity](#space-complexity)\n    - [Exercise: Space Complexity](#exercise-space-complexity)\n  - [**Section 4: How To Solve Coding Problems**](#section-4-how-to-solve-coding-problems)\n    - [What Are Companies Looking For?](#what-are-companies-looking-for)\n    - [What We Need For Coding Interviews](#what-we-need-for-coding-interviews)\n    - [Exercise: Interview Question](#exercise-interview-question)\n    - [Review Google Interview](#review-google-interview)\n  - [**Section 5: Data Structures: Introduction**](#section-5-data-structures-introduction)\n    - [How to choose the right Data Structure?](#how-to-choose-the-right-data-structure)\n    - [Examples of Data Structures in real life](#examples-of-data-structures-in-real-life)\n    - [What Is A Data Structure?](#what-is-a-data-structure)\n    - [How Computers Store Data](#how-computers-store-data)\n    - [Data Structures In Different Languages](#data-structures-in-different-languages)\n    - [Operations On Data Structures](#operations-on-data-structures)\n  - [**Section 6: Data Structures: Arrays**](#section-6-data-structures-arrays)\n    - [Arrays Introduction](#arrays-introduction)\n    - [Static vs Dynamic Arrays](#static-vs-dynamic-arrays)\n    - [Optional: Classes In Javascript](#optional-classes-in-javascript)\n    - [Implementing An Array](#implementing-an-array)\n    - [Exercise: Reverse A String](#exercise-reverse-a-string)\n    - [Exercise: Merge Sorted Arrays](#exercise-merge-sorted-arrays)\n    - [Interview Questions: Arrays](#interview-questions-arrays)\n  - [**Section 7: Data Structures: Hash Tables**](#section-7-data-structures-hash-tables)\n    - [Hash Tables Introduction](#hash-tables-introduction)\n    - [Hash Function](#hash-function)\n    - [Hash Collisions](#hash-collisions)\n    - [Exercise: Implement A Hash Table](#exercise-implement-a-hash-table)\n    - [Hash Tables VS Arrays](#hash-tables-vs-arrays)\n    - [Exercise: First Recurring Character](#exercise-first-recurring-character)\n    - [Hash Tables Review](#hash-tables-review)\n  - [**Section 8: Data Structures: Linked Lists**](#section-8-data-structures-linked-lists)\n    - [Linked Lists Introduction](#linked-lists-introduction)\n    - [What Is A Linked List?](#what-is-a-linked-list)\n    - [Exercise: Why Linked Lists?](#exercise-why-linked-lists)\n    - [Doubly Linked Lists](#doubly-linked-lists)\n    - [Linked Lists Review](#linked-lists-review)\n  - [**Section 9: Data Structures: Stacks + Queues**](#section-9-data-structures-stacks--queues)\n    - [Stacks + Queues Introduction](#stacks--queues-introduction)\n    - [Stacks](#stacks)\n    - [Queues](#queues)\n    - [Stacks VS Queues](#stacks-vs-queues)\n    - [Exercise: Stack Implementation (Linked Lists)](#exercise-stack-implementation-linked-lists)\n    - [Exercise: Stack Implementation (Array)](#exercise-stack-implementation-array)\n    - [Exercise: Queue Implementation (Linked Lists)](#exercise-queue-implementation-linked-lists)\n    - [Exercise: Queue Implementation (Array)](#exercise-queue-implementation-array)\n    - [Queues Using Stacks](#queues-using-stacks)\n    - [Stacks + Queues Review](#stacks--queues-review)\n  - [**Section 10: Data Structures: Trees**](#section-10-data-structures-trees)\n    - [Trees Introduction](#trees-introduction)\n    - [Binary Trees](#binary-trees)\n    - [Balanced VS Unbalanced BST](#balanced-vs-unbalanced-bst)\n    - [BST Pros and Cons](#bst-pros-and-cons)\n    - [Exercise: Binary Search Tree](#exercise-binary-search-tree)\n    - [AVL Trees vs Red Black Trees](#avl-trees-vs-red-black-trees)\n    - [Binary Heaps](#binary-heaps)\n    - [Trie](#trie)\n  - [**Section 11: Data Structures: Graphs**](#section-11-data-structures-graphs)\n    - [Types Of Graphs](#types-of-graphs)\n    - [Exercise: Graph Implementation](#exercise-graph-implementation)\n    - [Graphs Review](#graphs-review)\n    - [Data Structures Review](#data-structures-review)\n  - [**Section 12: Algorithms: Recursion**](#section-12-algorithms-recursion)\n    - [Introduction to Algorithms](#introduction-to-algorithms)\n    - [Stack Overflow](#stack-overflow)\n    - [Anatomy Of Recursion](#anatomy-of-recursion)\n    - [Exercise: Factorial](#exercise-factorial)\n    - [Exercise: Fibonacci](#exercise-fibonacci)\n    - [Recursive VS Iterative](#recursive-vs-iterative)\n    - [When To Use Recursion](#when-to-use-recursion)\n    - [Exercise: Reverse String With Recursion](#exercise-reverse-string-with-recursion)\n    - [Recursion Review](#recursion-review)\n  - [**Section 13: Algorithms: Sorting**](#section-13-algorithms-sorting)\n    - [Sorting Introduction](#sorting-introduction)\n    - [The Issue With sort()](#the-issue-with-sort)\n    - [Sorting Algorithms](#sorting-algorithms)\n    - [Exercise: Bubble Sort](#exercise-bubble-sort)\n    - [Exercise: Selection Sort](#exercise-selection-sort)\n    - [Dancing Algorithms](#dancing-algorithms)\n    - [Insertion Sort](#insertion-sort)\n    - [O(n log n)](#on-log-n)\n    - [Exercise: Merge Sort](#exercise-merge-sort)\n    - [Quick Sort](#quick-sort)\n    - [Which Sort Is Best?](#which-sort-is-best)\n    - [Heap Sort](#heap-sort)\n    - [Radix Sort + Counting Sort](#radix-sort--counting-sort)\n    - [Sorting Interview](#sorting-interview)\n  - [**Section 14: Algorithms: Searching + BFS + DFS**](#section-14-algorithms-searching--bfs--dfs)\n    - [Searching + Traversal Introduction](#searching--traversal-introduction)\n    - [Linear Search](#linear-search)\n    - [Binary Search](#binary-search)\n    - [BFS vs DFS](#bfs-vs-dfs)\n    - [breadthFirstSearch()](#breadthfirstsearch)\n    - [PreOrder, InOrder, PostOrder](#preorder-inorder-postorder)\n    - [depthFirstSearch()](#depthfirstsearch)\n    - [Exercise: Validate A BST](#exercise-validate-a-bst)\n    - [Graph Traversals](#graph-traversals)\n    - [Dijkstra + Bellman-Ford Algorithms](#dijkstra--bellman-ford-algorithms)\n  - [**Section 15: Algorithms: Dynamic Programming**](#section-15-algorithms-dynamic-programming)\n    - [Dynamic Programming Introduction](#dynamic-programming-introduction)\n    - [Memoization](#memoization)\n    - [Memoization](#memoization-1)\n    - [Fibonacci and Dynamic Programming](#fibonacci-and-dynamic-programming)\n    - [Interview Questions: Dynamic Programming](#interview-questions-dynamic-programming)\n  - [**Section 16: Non Technical Interviews**](#section-16-non-technical-interviews)\n    - [Section Overview](#section-overview)\n    - [During The Interview](#during-the-interview)\n    - [Tell Me About Yourself (1 min)](#tell-me-about-yourself-1-min)\n    - [Why Us?](#why-us)\n    - [Tell Me About A Problem You Have Solved](#tell-me-about-a-problem-you-have-solved)\n    - [What Is Your Biggest Weakness](#what-is-your-biggest-weakness)\n    - [Any Questions For Us?](#any-questions-for-us)\n    - [Secret Weapon](#secret-weapon)\n    - [After The Interview](#after-the-interview)\n    - [Section Summary](#section-summary)\n  - [**Section 17: Offer + Negotiation**](#section-17-offer--negotiation)\n    - [Negotiation 101](#negotiation-101)\n    - [Handling An Offer](#handling-an-offer)\n    - [Handling Multiple Offers](#handling-multiple-offers)\n    - [Getting A Raise](#getting-a-raise)\n    - [Negotiation Master](#negotiation-master)\n  - [**Section 19: Extras: Google, Amazon, Facebook Interview Questions**](#section-19-extras-google-amazon-facebook-interview-questions)\n\n## **Section 1: Introduction**\n\n[Interview Mind Map](https://coggle.it/diagram/W5u8QkZs6r4sZM3J/t/master-the-interview)\n\n- Getting the Interview\n- Big O Notation\n- Technical Interviews\n- Non Technical Interviews\n- Offer + Negotiation\n\n[Technical Interview Mind Map](https://coggle.it/diagram/W5E5tqYlrXvFJPsq/t/master-the-interview-click-here-for-course-link)\n\n- Data Structures\n- Algorithms\n\nFast Track\n\n- Getting The Interview\n- Non Technical Interview\n- Offer + Negotiation\n\nComplete\n\n- Everything\n\nTech Track\n\n- Big O\n- How To Solve Problems\n- Data Structures\n- Algorithms\n- Extra Coding Exercises\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 2: Getting More Interviews**\n\n- Resume\n- LinkedIn\n- Portfolio\n- Email\n\n**[⬆ back to top](#table-of-contents)**\n\n### Resume\n\nResources\n\n- [ResumeMaker.Online](https://www.resumemaker.online/)\n- [Resume Cheat Sheet](https://github.com/aneagoie/resume-checklist)\n- [Jobscan](https://www.jobscan.co/)\n- [Engineering Resume Templates](https://www.cakeresume.com/Engineering-resume-samples)\n- [This resume does not exist](https://thisresumedoesnotexist.com/)\n\nResume\n\n- One Page\n- Relevant Skills\n- Personalized\n- Online Link\n\n**[⬆ back to top](#table-of-contents)**\n\n### What If I Don't Have Enough Experience?\n\n[Creative Tim](https://www.creative-tim.com/)\n[Free HTML templates](http://www.mashup-template.com/)\n[Medium](https://medium.com/)\n\n- GitHub\n- Website\n- 1 - 2 Big Projects\n- Blog\n\n**[⬆ back to top](#table-of-contents)**\n\n### Portfolio\n\n- [Creative Tim](https://www.creative-tim.com/)\n- [HTML5/CSS3 Free Templates](http://www.mashup-template.com/templates.html)\n- [ZtM-Job-Board](https://github.com/zero-to-mastery/ZtM-Job-Board)\n- [Landing page templates for startups](https://cruip.com/)\n- [Free Bootstrap Templates \u0026 Themes](https://mdbootstrap.com/freebies/)\n- [15 Web Developer Portfolios to Inspire You](https://www.freecodecamp.org/news/15-web-developer-portfolios-to-inspire-you-137fb1743cae/)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Where To Find Jobs?\n\n[Where To Find Jobs?](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/learn/lecture/12111418#content)\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 3: Big O**\n\n### Setting Up Your Environment\n\n- [Repl.it](https://repl.it/)\n- [glot.io](https://glot.io/)\n- [RunJS](https://runjs.dev/)\n\n**[⬆ back to top](#table-of-contents)**\n\nPython, C/C++, Golang, Swift and JavaScript Solutions!\n\n- [Python](https://github.com/theja-m/Data-Structures-and-Algorithms)\n- [C/C++](https://github.com/shree1999/Data-Structures-and-Algorithms)\n- [Golang](https://github.com/punitpandey/DS-Algo)\n- [Swift](https://github.com/preetamjadakar/datastructures-swift)\n\n**[⬆ back to top](#table-of-contents)**\n\n### What Is Good Code?\n\nWhat Is Good Code?\n\n- Readable\n- Scalable [Big O]\n  - x-axis: Elements, y-axis: Operations\n  - Excellent, Good: O(log n), O(1)\n  - Fair: O(n)\n  - Bad: O(nlog n)\n  - Horrible: O(n^2), O(2^n), O(n!)\n\nBig O\n![](big-o-complexity.jpg)\n\n- [Know Thy Complexities](https://www.bigocheatsheet.com/)\n- [Big O Algorithm Complexity](big-o-complexity.pdf)\n- [Big O Cheat Sheet](big-o-cheatsheet.pdf)\n- [What is the difference between big oh, big omega and big theta notations?](https://www.quora.com/What-is-the-difference-between-big-oh-big-omega-and-big-theta-notations)\n\n**[⬆ back to top](#table-of-contents)**\n\n### O(n)\n\n```javascript\n// O(n): Linear time\nconst fish = ['dory', 'bruce', 'marlin', 'nemo']\nconst nemo = ['nemo']\nconst everyone = [\n  'dory',\n  'bruce',\n  'marlin',\n  'nemo',\n  'gill',\n  'bloat',\n  'nigel',\n  'squirt',\n  'darla',\n  'hank',\n]\nconst large = new Array(100000).fill('nemo')\n\nconst findNemo = (fish) =\u003e {\n  let t0 = performance.now()\n  for (let i = 0; i \u003c fish.length; i++) {\n    if (fish[i] === 'nemo') {\n      console.log('Found NEMO!')\n    }\n  }\n  let t1 = performance.now()\n  console.log('Call to find Nemo took ' + (t1 - t0) + ' milliseconds.')\n}\n\nfindNemo(large)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### O(1)\n\n```javascript\n// O(1): Constant time\nconst boxes = [0, 1, 2, 3, 4, 5]\n\nconst logFirstTwoBoxes = (boxes) =\u003e {\n  console.log(boxes[0])\t// O(1)\n  console.log(boxes[1])\t// O(1)\n}\n\nlogFirstTwoBoxes(boxes) // O(2)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Big O Calculation\n\n```javascript\n// What is the Big O of the below function?\n// Hint, you may want to go line by line\nconst funChallenge = (input) =\u003e {\n  let a = 10 // O(1)\n  a = 50 + 3 // O(1)\n\n  for (let i = 0; i \u003c input.length; i++) {\n    anotherFunction() // O(n)\n    let stranger = true // O(n)\n    a++ // O(n)\n  }\n  return a // O(1)\n}\n\n// 1 + 1 + 1 + n + n + n\n// Big O(3 + 3n)\n// O(n)\nfunChallenge()\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Big O Calculation 2\n\n```javascript\n// What is the Big O of the below function? \n// (Hint, you may want to go line by line)\nconst anotherFunChallenge = (input) =\u003e {\n  let a = 5 //O(1)\n  let b = 10 //O(1)\n  let c = 50 //O(1)\n  for (let i = 0; i \u003c input; i++) {\n    let x = i + 1 //O(n)\n    let y = i + 2 //O(n)\n    let z = i + 3 //O(n)\n  }\n  for (let j = 0; j \u003c input; j++) {\n    let p = j * 2 //O(n)\n    let q = j * 2 //O(n)\n  }\n  let whoAmI = \"I don't know\" //O(1)\n}\n\n// Big O(4 + 5n)\n// Big O(n)\nanotherFunChallenge(5)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Simplifying Big O\n\nRule Book\n\n1. Worst Case\n2. Remove Constants\n3. Different terms for inputs\n4. Drop Non Dominants\n\n**[⬆ back to top](#table-of-contents)**\n\n### Big O Rule 1 - Worst Case\n\n```javascript\n// Worst Case: n\nconst fish = ['dory', 'bruce', 'marlin', 'nemo']\nconst nemo = ['nemo']\nconst everyone = [\n  'dory',\n  'bruce',\n  'marlin',\n  'nemo',\n  'gill',\n  'bloat',\n  'nigel',\n  'squirt',\n  'darla',\n  'hank',\n]\nconst large = new Array(100000).fill('nemo')\n\nconst findNemo = (fish) =\u003e {\n  let t0 = performance.now()\n  for (let i = 0; i \u003c fish.length; i++) {\n    console.log('running')\n    if (fish[i] === 'nemo') {\n      console.log('Found NEMO!')\n      break\n    }\n  }\n  let t1 = performance.now()\n  console.log('Call to find Nemo took ' + (t1 - t0) + ' milliseconds.')\n}\n\nfindNemo(large)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Big O Rule 2 - Remove Constants\n\n```javascript\n// Big O(1 + n/2 + 100)\n// Big O(n/2 + 101)\n// Big O(n/2)\n// Big O(n)\nconst printFirstItemThenFirstHalfThenSayHi100Times = (items) =\u003e {\n  // O(1)\n  console.log(items[0])\n\n  const middleIndex = Math.floor(items.length / 2)\n  const index = 0\n\n  // O(n/2)\n  while (index \u003c middleIndex) {\n    console.log(items[index])\n    index++\n  }\n\n  // O(100)\n  for (let i = 0; i \u003c 100; i++) {\n    console.log('hi')\n  }\n}\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Big O Rule 3 - Different terms for inputs\n\n```javascript\n// boxes, boxes2 are 2 different terms for inputs\n// Big O(a + b)\nconst compressBoxesTwice = (boxes, boxes2) =\u003e {\n  boxes.forEach((box) =\u003e console.log(box)) // O(a)\n  boxes2.forEach((box) =\u003e console.log(box)) // O(b)\n}\n\ncompressBoxesTwice([1, 2, 3], [4, 5])\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### O(n^2)\n\n```javascript\n// Big O(a * b) - Quadratic Time\nconst boxes = ['a', 'b', 'c', 'd', 'e']\nconst logAllPairsOfArray = (array) =\u003e {\n  for (let i = 0; i \u003c array.length; i++) {\n    // O(a)\n    for (let j = 0; j \u003c array.length; j++) {\n      // O(b)\n      console.log(array[i], array[j])\n    }\n  }\n}\n\nlogAllPairsOfArray(boxes)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Big O Rule 4 - Drop Non Dominants\n\n```javascript\n// Big O(n + n^2)\n// Drop Non Dominants -\u003e Big O(n^2)\nconst printAllNumbersThenAllPairSums = (numbers) =\u003e {\n  // O(n)\n  console.log('these are the numbers:')\n  numbers.forEach((number) =\u003e console.log(number))\n\n  // O(n^2)\n  console.log('and these are their sums:')\n  numbers.forEach((firstNumber) =\u003e\n    numbers.forEach((secondNumber) =\u003e console.log(firstNumber + secondNumber))\n  )\n}\n\nprintAllNumbersThenAllPairSums([1, 2, 3, 4, 5])\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### What Does This All Mean?\n\nData Structures + Algorithms = Programs\n\n**[⬆ back to top](#table-of-contents)**\n\n### O(n!)\n\n[Example of O(n!)?](https://stackoverflow.com/questions/3953244/example-of-on)\n\n**[⬆ back to top](#table-of-contents)**\n\n### 3 Pillars Of Programming\n\nWhat is good code?\n\n1. Readable\n2. Scalable - Speed (Time Complexity)\n3. Scalable - memory (Space Complexity)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Space Complexity\n\nWhen a program executes it has two ways to remember things\n\n- Heap - Store variables\n- Stack - Keep track of function calls\n\nWhat causes Space Complexity?\n\n- Variables\n- Data Structures\n- Function Call\n- Allocations\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Space Complexity\n\n```javascript\n// Space complexity O(1)\nconst boooo = n =\u003e {\n  // space allocation for i is O(1)\n  for (let i = 0; i \u003c n.length; i++) {\n    console.log('booooo');\n  }\n}\nboooo([1, 2, 3, 4, 5])\n\n// Space complexity O(n)\nconst arrayOfHiNTimes = n =\u003e {\n  // space allocation for Data Structures hiArray is O(n)\n  const hiArray = [];\n  for (let i = 0; i \u003c n; i++) {\n    hiArray[i] = 'hi';\n  }\n  return hiArray;\n}\narrayOfHiNTimes(6)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 4: How To Solve Coding Problems**\n\n### What Are Companies Looking For?\n\n- Analytic Skills\n  - How can you think through a problem and analyze things?\n- Coding Skills\n  - Do you code well, by writing clean, simple, organized, readable code?\n- Technical Skills\n  - Do you know the fundamentals of the job you're applying for?\n  - Do you understand the pros and cons of different solutions?\n  - When you should use a certain data structure over the other?\n  - Why should we use a certain algorithm over another?\n- Communication Skills\n  - Does your personality match the companies’ culture?\n  - Can you communicate well with others?\n\n**[⬆ back to top](#table-of-contents)**\n\n### What We Need For Coding Interviews\n\n[Interview Cheat Sheet](interview-cheatsheet.pdf)\n\n[Data Structures](Top 8 Data Structures for Coding Interviews and practice interview questions)\n\n| Data Structures | Data Structures |\n| --------------- | --------------- |\n| Arrays          | Queues          |\n| Hash tables     | Trees           |\n| Linked Lists    | Tries           |\n| Stacks          | Graphs          |\n\n\n| Algorithms            |\n| --------------------- |\n| Recursion             |\n| Sorting               |\n| BFS + DFS (Searching) |\n| Dynamic Programming   |\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Interview Question\n\nGiven 2 arrays, create a function that let's a user know (true/false) whether these two arrays contain any common items.\n\n1. When the interviewer says the question, write down the key points at the top. Make sure you have all the details. Show how organized you are.\n\n```javascript\nconst array1 = ['a', 'b', 'c', 'x'];\nconst array2 = ['z', 'y', 'i'];\nshould return false.\n\nconst array1 = ['a', 'b', 'c', 'x'];\nconst array2 = ['z', 'y', 'x'];\nshould return true.\n```\n\n2. Make sure you double check: What are the inputs? What are the outputs?\n\n```javascript\nWhat are the inputs? \n2 parameters - arrays\n\nWhat are the outputs?\nreturn true or false\n```\n\n3. What is the most important value of the problem? Do you have time, and space and memory, etc.. What is the main goal?\n\n```javascript\n2 parameters - arrays - no size limit\n```\n\n4. Don't be annoying and ask too many questions.\n5. Start with the naive/brute force approach. First thing that comes into mind. It shows that you’re able to think well and critically (you don't need to write this code, just speak about it).\n\n```javascript\nconst array1 = ['a', 'b', 'c', 'x'];\nconst array2 = ['z', 'y', 'a'];\n\nconst containsCommonItem = (arr1, arr2) =\u003e {\n  for (let i=0; i \u003c arr1.length; i++) {\n    for ( let j=0; j \u003c arr2.length; j++) {\n      if(arr1[i] === arr2[j]) {\n        return true;\n      }\n    }\n  }\n  return false\n}\n\ncontainsCommonItem(array1, array2);\n```\n\n6. Tell them why this approach is not the best (i.e. O(n^2) or higher, not readable, etc...)\n\n```javascript\nTime Complexity - O(a*b)\nSpace Complexity - O(1)\n```\n\n7. Walk through your approach, comment things and see where you may be able to break things. Any repetition, bottlenecks like O(N^2), or unnecessary work? Did you use all the information the interviewer gave you? Bottleneck is the part of the code with the biggest Big O. Focus on that. Sometimes this occurs with repeated work as well.\n\n8. Before you start coding, walk through your code and write down the steps you are going to follow.\n\n```javascript\nconst array1 = ['a', 'b', 'c', 'x'];\nconst array2 = ['z', 'y', 'a'];\n\narray1 = obj {\n  a: true,\n  b: true,\n  c: true,\n  x: true\n}\narray2[index] === obj.properties\n```\n\n9.  Modularize your code from the very beginning. Break up your code into beautiful small pieces and add just comments if you need to.\n\n```javascript\nconst array1 = ['a', 'b', 'c', 'x'];\nconst array2 = ['z', 'y', 'a'];\nconst containsCommonItem2 = (arr1, arr2) =\u003e {\n  // loop through first array and create object where properties === items in the array\n  // can we assume always 2 params?\n  let map = {};\n  for (let i=0; i \u003c arr1.length; i++) {\n    if(!map[arr1[i]]) {\n      const item = arr1[i];\n      map[item] = true;\n    }\n  }\n\n  // loop through second array and check if item in second array exists on created object. \n  for (let j=0; j \u003c arr2.length; j++) {\n    if (map[arr2[j]]) {\n      return true;\n    }\n  }\n  return false\n}\n\ncontainsCommonItem2(array1, array2)\n\n// Time Complexity: O(a + b) \n// Space Complexity: O(a)\n```\n\n10. Start actually writing your code now. Keep in mind that the more you prepare and understand what you need to code, the better the whiteboard will go. So never start a whiteboard interview not being sure of how things are going to work out. That is a recipe for disaster. Keep in mind: A lot of interviews ask questions that you won’t be able to fully answer on time. So think: What can I show in order to show that I can do this and I am better than other coders. Break things up in Functions (if you can’t remember a method, just make up a function and you will at least have it there. Write something, and start with the easy part.\n\n```javascript\nconst array1 = ['a', 'b', 'c', 'x'];\nconst array2 = ['z', 'y', 'a'];\nconst arrToMap = arr1 =\u003e {\n  const map = {};\n  for (let i=0; i \u003c arr1.length; i++) {\n    if(!map[arr1[i]]) {\n      const item = arr1[i];\n      map[item] = true;\n    }\n  }\n  return map;\n}\n\nconst arrInMap = (map, arr2) =\u003e {\n  for (let j=0; j \u003c arr2.length; j++) {\n    if (map[arr2[j]]) {\n      return true;\n    }\n  }\n  return false\n}\n\nconst containsCommonItem2 = (arr1, arr2) =\u003e {\n  const map = arrToMap(arr1);\n  return arrInMap(map,arr2);\n}\n\ncontainsCommonItem2(array1, array2)\n```\n\n11. Think about error checks and how you can break this code. Never make assumptions about the input. Assume people are trying to break your code and that Darth Vader is using your function. How will you safeguard it? Always check for false inputs that you don’t want. Here is a trick: Comment in the code, the checks that you want to do… write the function, then tell the interviewer that you would write tests now to make your function fail (but you won't need to actually write the tests).\n\n12. Don’t use bad/confusing names like i and j. Write code that reads well.\n\n13. Test your code: Check for no params, 0, undefined, null, massive arrays, async code, etc… Ask the interviewer if we can make assumption about the code. Can you make the answer return an error? Poke holes into your solution. Are you repeating yourself?\n\n```javascript\nconst arrToMap = (arr1 = []) =\u003e {\n  const map = {};\n  for (let i=0; i \u003c arr1.length; i++) {\n    if(!map[arr1[i]]) {\n      const item = arr1[i];\n      map[item] = true;\n    }\n  }\n  return map;\n}\n\nconst arrInMap = (map, arr2) =\u003e {\n  for (let j=0; j \u003c arr2.length; j++) {\n    if (map[arr2[j]]) {\n      return true;\n    }\n  }\n  return false\n}\n\nconst containsCommonItem2 = (arr1 = [], arr2 = []) =\u003e {\n  const map = arrToMap(arr1);\n  return arrInMap(map,arr2);\n}\n\ncontainsCommonItem2()\n```\n\n14.  Finally talk to the interviewer where you would improve the code. Does it work? Are there different approaches? Is it readable? What would you google to improve? How can performance be improved? Possibly: Ask the interviewer what was the most interesting solution you have seen to this problem\n\n```javascript\nconst containsCommonItem3 = (arr1, arr2) \n  =\u003e arr1.some(item =\u003e arr2.includes(item))\n\ncontainsCommonItem3(array1, array2)\n```\n\n15. If your interviewer is happy with the solution, the interview usually ends here. It is also common that the interviewer asks you extension questions, such as how you would handle the problem if the whole input is too large to fit into memory, or if the input arrives as a stream. This is a common follow-up question at Google, where they care a lot about scale. The answer is usually a divide-and-conquer approach — perform distributed processing of the data and only read certain chunks of the input from disk into memory, write the output back to disk and combine them later.\n\n**[⬆ back to top](#table-of-contents)**\n\n### Review Google Interview\n\n```javascript\n// [1, 2, 3, 9] Sum = 8, No\n// [1, 2, 4, 4] Sum = 8, Yes\n\n// Naive Approach\nconst hasPairWithSum = (arr, sum) =\u003e {\n  const len = arr.length;\n  for(let i =0; i\u003clen-1; i++){\n     for(let j = i+1;j\u003clen; j++){\n        if (arr[i] + arr[j] === sum)\n            return true;\n     }\n  }\n  return false;\n}\n\nhasPairWithSum([1, 2, 3, 9], 8)\nhasPairWithSum([1, 2, 4, 4], 8)\n\n// Better Approach\nconst hasPairWithSum2 = (arr, sum) =\u003e {\n  const mySet = new Set();\n  const len = arr.length;\n  for (let i = 0; i \u003c len; i++){\n    if (mySet.has(arr[i])) {\n      return true;\n    }\n    mySet.add(sum - arr[i]);\n  }\n  return false;\n}\n\nhasPairWithSum2([1, 2, 3, 9], 8)\nhasPairWithSum2([1, 2, 4, 4], 8)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 5: Data Structures: Introduction**\n\n### How to choose the right Data Structure?\n\n[Choosing the Right Data Structure to solve problems](https://www.careerdrill.com/blog/coding-interview/choosing-the-right-data-structure-to-solve-problems/)\n\n![](choose-data-structures.png)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Examples of Data Structures in real life\n\n- [Data Structures](data-structures.pdf)\n- [Real-Life Examples of Data Structures](data-structures-in-real-life.pdf)\n- [Examples of Data Structures in real life](https://stackoverflow.com/questions/54466641/examples-of-data-structures-in-real-life)\n- [Data Structures In The Real World — Linked List](https://medium.com/journey-of-one-thousand-apps/data-structures-in-the-real-world-508f5968545a)\n- [Real world data structures: tables and graphs in JavaScript](https://www.freecodecamp.org/news/real-world-data-structures-tables-and-graphs-in-javascript-bcb70c929495/)\n- [The Real-Life Applications Of Graph Data Structures You Must Know](https://leapgraph.com/graph-data-structures-applications)\n- [How do I use algorithms and data structure in real life?](https://www.onlinebooksreview.com/articles/how-do-i-use-algorithms-and-data-structures-in-real-life)\n\n**[⬆ back to top](#table-of-contents)**\n\n### What Is A Data Structure?\n\n- A data structure is a collection of values.\n- The values can have relationships among them and they can have functions applied to them.\n- All programs are we're modeling real life scenarios.\n\nQuestion\n\n- How to build one?\n- How to Use it?\n\n**[⬆ back to top](#table-of-contents)**\n\n### How Computers Store Data\n\n- [Computer Memory](http://statmath.wu.ac.at/courses/data-analysis/itdtHTML/node55.html)\n- [Registers and RAM](https://www.youtube.com/watch?v=fpnE6UAfbtU)\n\n- CPU: access RAM and Storage for information\n- RAM: fast but limited, non-persistent\n- Storage: more but slow, persistent\n\n**[⬆ back to top](#table-of-contents)**\n\n### Data Structures In Different Languages\n\n[Data Structures — Language Support (Part 3)](https://medium.com/omarelgabrys-blog/data-structures-language-support-5f70f8312e84)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Operations On Data Structures\n\n- Insertion\n- Deletion\n- Traversal\n- Searching\n- Sorting\n- Access\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 6: Data Structures: Arrays**\n\n### Arrays Introduction\n\nArray vs Object\n\n- Arrays for storing ordered collections.\n- Objects for storing keyed collections.\n\n[Real life examples](https://www.youtube.com/watch?v=DBZoB8r4XY8)\n\n- [Cinema Book Challenge](https://www.101computing.net/cinema-booking-challenge/)\n\nArray\n\n| Operation | Big O |\n| --------- | ----- |\n| lookup    | O(1)  |\n| push      | O(1)  |\n| insert    | O(n)  |\n| delete    | O(n)  |\n\n```javascript\n// 4 * 4 = 16 bytes of storage\nconst strings = ['a', 'b', 'c', 'd'];\nstrings[2]\n\nconst numbers = [1, 2, 3, 4, 5];\n\n//push\nstrings.push('e');  // O(1)\n\n//pop\nstrings.pop();  // O(1)\nstrings.pop();  // O(1)\n\n//unshift\n// 'x' will push all elements to their right\n// ['x', 'a', 'b', 'c', 'd'];\n//   0    1    2    3    4\nstrings.unshift('x')  // O(n)\n\n//splice\nstrings.splice(2, 0, 'alien');  // O(n)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Static vs Dynamic Arrays\n\nJavaScript Array is dynamic \n\n| Array Operation | Big O | Dynamic Array | Big O        |\n| --------------- | ----- | ------------- | ------------ |\n| lookup          | O(1)  | lookup        | O(1)         |\n| push            | O(1)  | append*       | O(1) or O(n) |\n| insert          | O(n)  | insert        | O(n)         |\n| delete          | O(n)  | delete        | O(n)         |\n\n**[⬆ back to top](#table-of-contents)**\n\n### Optional: Classes In Javascript\n\n- [Understanding Classes in JavaScript](https://www.digitalocean.com/community/tutorials/understanding-classes-in-javascript)\n- [Arrow Functions in Class Properties Might Not Be As Great As We Think](https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1)\n\n```javascript\nclass Hero {\n  constructor(name, level) {\n    this.name = name;\n    this.level = level;\n  }\n  greet = () =\u003e {\n    return `${this.name} says hello.`;\n  }\n}\n\nclass Mage extends Hero {\n  constructor(name, level, spell) {\n    super(name, level);\n    this.spell = spell;\n  }\n  greet() {\n    super.greet()\n  }\n}\n\nconst hero1 = new Hero('Varg', 1);\nconst hero2 = new Mage('Lejon', 2, 'Magic Missile');\nhero2.greet()\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Implementing An Array\n\n```javascript\nclass MyArray {\n  constructor() {\n    this.length = 0;\n    this.data = {};\n  }\n  get(index) {\n    return this.data[index];  // O(1)\n  }\n\n  push(item) {  \n    this.data[this.length] = item;  // O(1)\n    this.length++;\n    return this.data;\n  }\n  \n  pop() {\n    const lastItem = this.data[this.length - 1];  // O(1)\n    delete this.data[this.length - 1];\n    this.length--;\n    return lastItem;\n  }\n  \n  deleteAtIndex(index) {\n    const item = this.data[index];\n    this.shiftItems(index); // O(n)\n    return item;\n  }\n  \n  shiftItems(index) {\n    for (let i = index; i \u003c this.length - 1; i++) { \n      this.data[i] = this.data[i + 1];  // O(n)\n    }\n    delete this.data[this.length - 1];\n    this.length--;\n  }\n}\n\nconst myArray = new MyArray();\nmyArray.push('hi');\nmyArray.push('you');\nmyArray.push('!');\nmyArray.get(0);\nmyArray.pop();\nmyArray.deleteAtIndex(0);\nmyArray.push('are');\nmyArray.push('nice');\nmyArray.shiftItems(0);\n```\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Reverse A String\n\n```javascript\nconst reverse1 = (str = '') =\u003e {\n  if(!str || typeof str != 'string' || str.length \u003c 2 ) return str;\n  \n  const backwards = [];\n  const totalItems = str.length - 1;\n  for(let i = totalItems; i \u003e= 0; i--){\n    backwards.push(str[i]);\n  }\n  return backwards.join('');\n}\n\nconst reverse2 = (str = '') =\u003e str.split('').reverse().join('');\nconst reverse3 = (str = '') =\u003e [...str].reverse().join('');\n\nreverse1('Timbits Hi')\nreverse2('Timbits Hi')\nreverse3('Timbits Hi')\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Merge Sorted Arrays\n\n```javascript\nconst ascendingSort = (a, b) =\u003e a - b;\nconst descendingSort = (a, b) =\u003e b - a;\n\nconst mergeSortedArrays = (arr1, arr2) =\u003e arr1.concat(arr2).sort(ascendingSort);\nmergeSortedArrays([0,3,4,31], [3,4,6,30]);\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Interview Questions: Arrays\n\n- [LeetCode](https://leetcode.com/)\n- [Interview Questions](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/learn/lecture/12310382#content)\n\n```javascript\n// Given an array of integers, return indices of the two numbers such that they add up to a specific target.\n// You may assume that each input would have exactly one solution, and you may not use the same element twice.\n\n// Given nums = [2, 7, 11, 15], target = 9,\n// Because nums[0] + nums[1] = 2 + 7 = 9,\n// return [0, 1].\n\nconst twoSum = (nums, target) =\u003e {\n  let low = 0;\n  let high = nums.length - 1;\n  while(low \u003c high) {\n    if(nums[low] + nums[high] === target) return [low, high];\n    else if(nums[low] + nums[high] \u003e target) high--;\n    else low++;\n  }\n};\n\ntwoSum([2, 3, 4, 5, 6], 10)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 7: Data Structures: Hash Tables**\n\n### Hash Tables Introduction\n\n| Operation | Big O |\n| --------- | ----- |\n| insert    | O(1)  |\n| lookup    | O(1)  |\n| delete    | O(n)  |\n| search    | O(n)  |\n\n[Hash Table Animation](https://www.cs.usfca.edu/~galles/visualization/OpenHash.html)\n\n![](hash-tables.jpg)\n\nExamples of Hash Tables\n\n- [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) is a collection of keyed data items, just like an Object. But the main difference is that Map allows keys of any type.\n- A [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) is a special type collection – \"set of values\" (without keys), where each value may occur only once.\n- [Map and Set](https://javascript.info/map-set)\n- [Array vs Set vs Map vs Object](https://codeburst.io/array-vs-set-vs-map-vs-object-real-time-use-cases-in-javascript-es6-47ee3295329b)\n- [ES6 — Map vs Object — What and when?](https://medium.com/front-end-weekly/es6-map-vs-object-what-and-when-b80621932373)\n- [ES6 — Set vs Array — What and when?](https://medium.com/front-end-weekly/es6-set-vs-array-what-and-when-efc055655e1a)\n- [The Importance of Hash Tables](https://medium.com/coderbyte/importance-of-hash-tables-c429a2b523b8)\n\nReal life examples\n\n- Suppose I stay in a hotel for a few days, because I attend a congress on hashing. At the end of the day, when I return to the hotel, I ask the desk clerk if there are any messages for me. Behind his back is a dovecot-like cupboard, with 26 entries, labeled A to Z. Because he knows my last name, he goes to the slot labeled W, and takes out three letters. One is for Robby Williams, one is for Jimmy Webb, and one is for me.\n\nThe clerk only had to inspect three letters. How many letters would he have to inspect if there would have been only one letter box?\n\n**[⬆ back to top](#table-of-contents)**\n\n### Hash Function\n\n[md5 Hash Generator](http://www.miraclesalad.com/webtools/md5.php)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Hash Collisions\n\n![](hash-tables-collisions.jpg)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Implement A Hash Table\n\n```javascript\nclass HashTable {\n  constructor(size){\n    this.data = new Array(size);\n    // this.data = [];\n  }\n\n  _hash(key) {\n    let hash = 0;\n    for (let i =0; i \u003c key.length; i++){\n        hash = (hash + key.charCodeAt(i) * i) % this.data.length\n    }\n    return hash;\n  }\n\n  set(key, value) {\n    const address = this._hash(key);\n    if (!this.data[address]) {\n      this.data[address] = [];\n    }\n    this.data[address].push([key, value]);\n    return this.data;\n  }\n\n  get(key) {\n    const address = this._hash(key);\n    const currentBucket = this.data[address]\n    return currentBucket \n      ? currentBucket.find(item =\u003e item[0] === key)[1] \n      : undefined\n  }\n\n  keys() {\n    return this.data.filter(item =\u003e !!item).map(item =\u003e item[0][0]);\n  }\n}\n\nconst myHashTable = new HashTable(50);\nmyHashTable.set('grapes', 10000)\nmyHashTable.get('grapes')\nmyHashTable.set('oranges', 54)\nmyHashTable.get('oranges')\nmyHashTable.set('apples', 9)\nmyHashTable.get('apples')\nmyHashTable.keys()\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Hash Tables VS Arrays\n\nArrays\n\n| Operation | Big O |\n| --------- | ----- |\n| search    | O(n)  |\n| lookup    | O(1)  |\n| push*     | O(1)  |\n| insert    | O(n)  |\n| delete    | O(n)  |\n\nHash Tables\n\n| Operation | Big O |\n| --------- | ----- |\n| search    | O(1)  |\n| insert    | O(1)  |\n| lookup    | O(n)  |\n| delete    | O(n)  |\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: First Recurring Character\n\n```javascript\n//Google Question\n//Given an array = [2,5,1,2,3,5,1,2,4]:\n//It should return 2\n\n//Given an array = [2,1,1,2,3,5,1,2,4]:\n//It should return 1\n\n//Given an array = [2,3,4,5]:\n//It should return undefined\n\n//Bonus... What if we had this:\n// [2,5,5,2,3,5,1,2,4]\n// return 5 because the pairs are before 2,2\n\nconst firstRecurringCharacter1 = input =\u003e {\n  const map = []\n  for (let i = 0; i \u003c input.length; i++) {\n    const foundItem = map.find(item =\u003e item === input[i]);\n    if(!!foundItem) return input[i]; \n    else map.push(input[i]);\n  }\n  return undefined;\n}\n\nfirstRecurringCharacter1([2,5,1,2,3,5,1,2,4])\nfirstRecurringCharacter1([2,1,1,2,3,5,1,2,4])\nfirstRecurringCharacter1([2,3,4,5])\nfirstRecurringCharacter1([2,5,5,2,3,5,1,2,4])\n\nconst firstRecurringCharacter2 = input =\u003e {\n  const mySet = new Set()\n  for (let i = 0; i \u003c input.length; i++) {\n    const isFound = mySet.has(input[i]);\n    if(isFound) return input[i]; \n    else mySet.add(input[i]);\n  }\n  return undefined;\n}\n\nfirstRecurringCharacter2([2,5,1,2,3,5,1,2,4])\nfirstRecurringCharacter2([2,1,1,2,3,5,1,2,4])\nfirstRecurringCharacter2([2,3,4,5])\nfirstRecurringCharacter2([2,5,5,2,3,5,1,2,4])\n\nconst firstRecurringCharacter3 = input =\u003e {\n  const myMap = new Map()\n  for (let i = 0; i \u003c input.length; i++) {\n    const isFound = myMap.has(input[i]) \n    if (isFound) return input[i]\n    else myMap.set(input[i], i)\n  }\n  return undefined;\n}\n\nfirstRecurringCharacter3([2,5,1,2,3,5,1,2,4])\nfirstRecurringCharacter3([2,1,1,2,3,5,1,2,4])\nfirstRecurringCharacter3([2,3,4,5])\nfirstRecurringCharacter3([2,5,5,2,3,5,1,2,4])\n\nconst firstRecurringCharacter4 = input =\u003e {\n  const hashtable = {}\n  for (let item of input) {\n    if(!hashtable[item]) hashtable[item] = true\n    else return item; \n  }\n  return undefined;\n}\n\nfirstRecurringCharacter4([2,5,1,2,3,5,1,2,4])\nfirstRecurringCharacter4([2,1,1,2,3,5,1,2,4])\nfirstRecurringCharacter4([2,3,4,5])\nfirstRecurringCharacter4([2,5,5,2,3,5,1,2,4])\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Hash Tables Review\n\n[Completed JavaScript Data Structure Course, and Here is What I Learned About Hash Table.](https://dev.to/maikomiyazaki/completed-javascript-data-structure-course-and-here-is-what-i-learned-about-hash-table-2ecm)\n\nPros\n\n- Fast lookups*\n- Fast inserts\n- Flexible Keys\n*Good collision resolution needed\n\nCons\n\n- Unordered\n- Slow key interation\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 8: Data Structures: Linked Lists**\n\n### Linked Lists Introduction\n\nType\n\n- Single Linked List\n- Double Linked List\n\n[Real life examples](https://www.youtube.com/watch?v=Z_fNkGm1oN4)\n\n- Image viewer – Previous and next images are linked, hence can be accessed by next and previous button.\n- Previous and next page in web browser – We can access previous and next url searched in web browser by pressing back and next button since, they are linked as linked list.\n- Music Player – Songs in music player are linked to previous and next song. you can play songs either from starting or ending of the list.\n\n**[⬆ back to top](#table-of-contents)**\n\n### What Is A Linked List?\n\n- head -\u003e apples\n- tail -\u003e pears\n\nconst basket = ['apples', 'grapes', 'pears']\n\nlinked list: apples --\u003e grapes --\u003e pears\n\napples\n8947 --\u003e grapes\n          8742 --\u003e pears\n                    372 --\u003e null\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Why Linked Lists?\n\n[VisuAlgo Linked List](https://visualgo.net/en/list)\n\nLinked Lists\n\n| Operation | Big O |\n| --------- | ----- |\n| prepend   | O(1)  |\n| append    | O(1)  |\n| lookup    | O(n)  |\n| insert    | O(n)  |\n| delete    | O(n)  |\n\n**[⬆ back to top](#table-of-contents)**\n\n```javascript\n// Create the below linked list:\n// myLinkedList = {\n//   head: { value: 10, \n//           next: { value: 5, \n//                   next: { value: 16,\n//                           next: null\n//                         }\n//                 }\n//         }\n// };\nclass Node {\n  constructor(value) {\n    this.value = value;\n    this.next = null;\n  }\n}\n\nclass LinkedList {\n  constructor(value) {\n    this.head = new Node(value);\n    this.tail = this.head;\n    this.length = 1;\n  }\n  append(value) {\n    const newNode = new Node(value);\n    this.tail.next = newNode;\n    this.tail = newNode;\n    this.length++;\n    return this;\n  }\n  prepend(value) {\n    const newNode = new Node(value);\n    newNode.next = this.head;\n    this.head = newNode;\n    this.length++;\n    return this;\n  }\n  printList() {\n    const array = [];\n    let currentNode = this.head;\n    while(currentNode !== null){\n        array.push(currentNode.value)\n        currentNode = currentNode.next\n    }\n    return array;\n  }\n  insert(index, value){\n    if(index \u003e= this.length) {\n      return this.append(value);\n    }\n    const newNode = new Node(value);\n    const leader = this.traverseToIndex(index-1);\n    const holdingPointer = leader.next;\n    leader.next = newNode;\n    newNode.next = holdingPointer;\n    this.length++;\n    return this.printList();\n  }\n  traverseToIndex(index) {\n    let counter = 0;\n    let currentNode = this.head;\n    while(counter !== index){\n      currentNode = currentNode.next;\n      counter++;\n    }\n    return currentNode;\n  }\n  remove(index) {     \n    const leader = this.traverseToIndex(index-1);\n    const unwantedNode = leader.next;\n    leader.next = unwantedNode.next;\n    this.length--;\n    return this.printList();\n  }\n}\n\nconst myLinkedList = new LinkedList(10);\nmyLinkedList\nmyLinkedList.append(5);\nmyLinkedList.append(16);\nmyLinkedList.prepend(1);\nmyLinkedList.insert(2, 99);\nmyLinkedList.insert(20, 88);\nmyLinkedList.remove(2);\n```\n**[⬆ back to top](#table-of-contents)**\n\n### Doubly Linked Lists\n\n```javascript\nclass Node {\n  constructor(value) {\n    this.value = value;\n    this.next = null;\n    this.prev = null;\n  }\n}\n\nclass DoublyLinkedList {\n  constructor(value) {\n    this.head = new Node(value);\n    this.tail = this.head;\n    this.length = 1;\n  }\n  append(value) {\n    const newNode = new Node(value);\n    newNode.prev = this.tail\n    this.tail.next = newNode;\n    this.tail = newNode;\n    this.length++;\n    return this;\n  }\n  prepend(value) {\n    const newNode = new Node(value);\n    newNode.next = this.head;\n    this.head.prev = newNode\n    this.head = newNode;\n    this.length++;\n    return this;\n  }\n  printList() {\n    const array = [];\n    let currentNode = this.head;\n    while(currentNode !== null){\n      array.push(currentNode.value)\n      currentNode = currentNode.next\n    }\n    return array;\n  }\n  insert(index, value){\n    if(index \u003e= this.length) {\n      return this.append(value);\n    }\n    \n    const newNode = new Node(value);\n    const leader = this.traverseToIndex(index-1);\n    const follower = leader.next;\n    leader.next = newNode;\n    newNode.prev = leader;\n    newNode.next = follower;\n    follower.prev = newNode;\n    this.length++;\n    console.log(this)\n    return this.printList();\n  }\n  traverseToIndex(index) {\n    //Check parameters\n    let counter = 0;\n    let currentNode = this.head;\n    while(counter !== index){\n      currentNode = currentNode.next;\n      counter++;\n    }\n    return currentNode;\n  }\n  remove(index) {  \n    const leader = this.traverseToIndex(index-1);\n    const unwantedNode = leader.next;\n    leader.next = unwantedNode.next;\n    this.length--;\n    return this.printList();\n  }\n  reverse() {\n    if (!this.head.next) {\n      return this.head;\n    }\n    let first = this.head;\n    this.tail = this.head;\n    let second = first.next;\n\n    while(second) {\n      const temp = second.next;\n      second.next = first;\n      first = second;\n      second = temp;\n    }\n\n    this.head.next = null;\n    this.head = first;\n    return this.printList();\n  }\n}\n\nconst myLinkedList = new DoublyLinkedList(10);\nmyLinkedList\nmyLinkedList.append(5)\nmyLinkedList.append(16)\nmyLinkedList.prepend(1)\nmyLinkedList.insert(2, 99)\nmyLinkedList.insert(20, 88)\nmyLinkedList.printList()\nmyLinkedList.remove(2)\nmyLinkedList.reverse()\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Linked Lists Review\n\nPros\n\n- Fast Insertion\n- Fast Deletion\n- Ordered\n- Flexible Size\n\nCons\n\n- Slow Lookup\n- More Memory\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 9: Data Structures: Stacks + Queues**\n\n### Stacks + Queues Introduction\n\n[Stack and Queue Real World Examples](https://www.youtube.com/watch?v=M0TpZhS4LuM)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Stacks\n\nReal life examples\n\n- Browser history\n- Store undo/redo operations in a word processor\n- Maze\n\nStacks: LIFO\n\n| Operation | Big O |\n| --------- | ----- |\n| lookup    | O(n)  |\n| pop       | O(1)  |\n| push      | O(1)  |\n| peek      | O(1)  |\n\n**[⬆ back to top](#table-of-contents)**\n\n### Queues\n\nReal life examples - Scheduling\n\n- waitlist app to buy tickets for a concert\n- restaurant app to see if you can get a table\n- uber to grab a ride\n- printer\n\nStacks: FIFO\n\n| Operation | Big O |\n| --------- | ----- |\n| lookup    | O(n)  |\n| enqueue   | O(1)  |\n| dequeue   | O(1)  |\n| peek      | O(1)  |\n\n### Stacks VS Queues\n\nStacks\n\n- Implement with Arrays and Linked Lists\n\nQueues\n\n- Implement with Linked Lists\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Stack Implementation (Linked Lists)\n\n```javascript\nclass Node {\n  constructor(value){\n    this.value = value;\n    this.next = null;\n  }\n}\n\nclass Stack {\n  constructor(){\n    this.top = null;\n    this.bottom = null;\n    this.length = 0;\n  }\n  peek() {  // O(1)\n    return this.top;\n  }\n  push(value){  // O(1)\n    const newNode = new Node(value);\n    if (this.length === 0) {\n      this.top = newNode;\n      this.bottom = newNode;\n    } else {\n      const holdingPointer = this.top;\n      this.top = newNode;\n      this.top.next = holdingPointer;\n    }\n    this.length++;\n    return this;\n  }\n  pop(){  // O(1)\n    if (!this.top) {\n      return null;\n    }\n    if (this.top === this.bottom) {\n      this.bottom = null;\n    }\n    const holdingPointer = this.top;\n    this.top = this.top.next;\n    this.length--;\n    return this;\n  }\n}\n\nconst myStack = new Stack();\nmyStack.peek();\nmyStack.push('google');\nmyStack.push('udemy');\nmyStack.push('discord');\nmyStack.peek();\nmyStack.pop();\nmyStack.pop();\nmyStack.pop();\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Stack Implementation (Array)\n\n```javascript\nclass Stack {\n  constructor(){\n    this.array = [];\n  }\n  peek() {  // O(1)\n    return this.array[this.array.length-1];\n  }\n  push(value){\n    this.array.push(value); // O(1)\n    return this;\n  }\n  pop(){\n    this.array.pop(); // O(1)\n    return this;\n  }\n}\n\nconst myStack = new Stack();\nmyStack.peek();\nmyStack.push('google');\nmyStack.push('udemy');\nmyStack.push('discord');\nmyStack.peek();\nmyStack.pop();\nmyStack.pop();\nmyStack.pop();\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Queue Implementation (Linked Lists)\n\n```javascript\nclass Node {\n  constructor(value) {\n    this.value = value;\n    this.next = null;\n  }\n}\n\nclass Queue {\n  constructor(){\n    this.first = null;\n    this.last = null;\n    this.length = 0;\n  }\n  peek() {  // O(1)\n    return this.first;\n  }\n  enqueue(value){ // O(1)\n    const newNode = new Node(value);\n    if (this.length === 0) {\n      this.first = newNode;\n      this.last = newNode;\n    } else {\n      this.last.next = newNode;\n      this.last = newNode;\n    }\n    this.length++;\n    return this;\n  }\n  dequeue(){  // O(1)\n    if (!this.first) {\n      return null;\n    }\n    if (this.first === this.last) {\n      this.last = null;\n    }\n    const holdingPointer = this.first;\n    this.first = this.first.next;\n    this.length--;\n    return this;\n  }\n}\n\nconst myQueue = new Queue();\nmyQueue.peek();\nmyQueue.enqueue('Joy');\nmyQueue.enqueue('Matt');\nmyQueue.enqueue('Pavel');\nmyQueue.peek();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.peek();\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Queue Implementation (Array)\n\n```javascript\nclass Queue {\n  constructor(){\n    this.array = [];\n  }\n  peek() {\n    return this.array[0]; // O(1)\n  }\n  enqueue(value){\n    this.array.push(value); // O(1)\n    return this;\n  }\n  dequeue(){\n    this.array.shift(); // O(n)\n    return this;\n  }\n}\n\nconst myQueue = new Queue();\nmyQueue.peek();\nmyQueue.enqueue('Joy');\nmyQueue.enqueue('Matt');\nmyQueue.enqueue('Pavel');\nmyQueue.peek();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.peek();\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Queues Using Stacks\n\n```javascript\nclass CrazyQueue {\n  constructor() {\n    this.first = [];\n    this.last = [];\n  }\n\n  enqueue(value) {\n    const length = this.first.length;\n    for (let i = 0; i \u003c length; i++) {\n      this.last.push(this.first.pop());\n    }\n    this.last.push(value);\n    return this;\n  }\n\n  dequeue() {\n    const length = this.last.length;\n    for (let i = 0; i \u003c length; i++) {\n      this.first.push(this.last.pop());\n    }\n    this.first.pop();\n    return this;\n  }\n  peek() {\n    if (this.last.length \u003e 0) {\n      return this.last[0];\n    }\n    return this.first[this.first.length - 1];\n  }\n}\n\nconst myQueue = new CrazyQueue();\nmyQueue.peek();\nmyQueue.enqueue('Joy');\nmyQueue.enqueue('Matt');\nmyQueue.enqueue('Pavel');\nmyQueue.peek();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.dequeue();\nmyQueue.peek();\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Stacks + Queues Review\n\nPros\n\n- Fast Operations\n- Fast Peek\n- Ordered\n\nCons\n\n- Slow Lookup\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 10: Data Structures: Trees**\n\n### Trees Introduction\n\nReal life examples\n\n- DOM\n- Chess Game use tree data structure to make decisions\n- Facebook comments\n- Family Tree\n- Abstract Syntax Tree\n\n**[⬆ back to top](#table-of-contents)**\n\n### Binary Trees\n\nTypes of Binary Tree\n\n- Perfect Binary Tree\n- Full Binary Tree\n\n[Binary Search Tree](https://visualgo.net/bn/bst?slide=1)\n\n| Operation | Big O    |\n| --------- | -------- |\n| lookup    | O(log n) |\n| insert    | O(log n) |\n| delete    | O(log n) |\n\nO(log n)\n\n- Level 0: 2^0 = 1\n- Level 1: 2^1 = 2\n- Level 2: 2^2 = 4\n- Level 3: 2^3 = 8\n\nNos. of nodes = 2 ^ h - 1\nlog nodes = steps\n\nlog 100 = 2\n10^2 = 100\n\n```\n   101\n   /  \\\n  33   105\n / \\    / \\\n9  37  104 144\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Balanced VS Unbalanced BST\n\nUnbalanced BST\n\n| Operation | Big O |\n| --------- | ----- |\n| lookup    | O(n)  |\n| insert    | O(n)  |\n| delete    | O(n)  |\n\n**[⬆ back to top](#table-of-contents)**\n\n### BST Pros and Cons\n\nPros\n\n- Better than O(n)\n- Ordered\n- Flexible Size\n\nCons\n\n- No O(1) operations\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Binary Search Tree\n\n```javascript\nclass Node {\n  constructor(value) {\n    this.left = null;\n    this.right = null;\n    this.value = value;\n  }\n}\n\nclass BinarySearchTree {\n  constructor() {\n    this.root = null;\n  }\n  insert(value) {\n    const newNode = new Node(value);\n    if (this.root === null) {\n      this.root = newNode;\n      return this;\n    } else {\n      let currentNode = this.root;\n      while (true) {\n        if (value \u003c currentNode.value) {\n          //Left\n          if (!currentNode.left) {\n            currentNode.left = newNode;\n            return this;\n          }\n          currentNode = currentNode.left;\n        } else {\n          //Right\n          if (!currentNode.right) {\n            currentNode.right = newNode;\n            return this;\n          }\n          currentNode = currentNode.right;\n        }\n      }\n    }\n  }\n  lookup(value) {\n    if (!this.root) {\n      return false;\n    }\n    let currentNode = this.root;\n    while (currentNode) {\n      if (value \u003c currentNode.value) {\n        currentNode = currentNode.left;\n      } else if (value \u003e currentNode.value) {\n        currentNode = currentNode.right;\n      } else if (currentNode.value === value) {\n        return currentNode;\n      }\n    }\n    return null;\n  }\n  remove(value) {\n    if (!this.root) {\n      return false;\n    }\n    let currentNode = this.root;\n    let parentNode = null;\n    while (currentNode) {\n      if (value \u003c currentNode.value) {\n        parentNode = currentNode;\n        currentNode = currentNode.left;\n      } else if (value \u003e currentNode.value) {\n        parentNode = currentNode;\n        currentNode = currentNode.right;\n      } else if (currentNode.value === value) {\n        //We have a match, get to work!\n\n        //Option 1: No right child:\n        if (currentNode.right === null) {\n          if (parentNode === null) {\n            this.root = currentNode.left;\n          } else {\n            //if parent \u003e current value, make current left child a child of parent\n            if (currentNode.value \u003c parentNode.value) {\n              parentNode.left = currentNode.left;\n\n              //if parent \u003c current value, make left child a right child of parent\n            } else if (currentNode.value \u003e parentNode.value) {\n              parentNode.right = currentNode.left;\n            }\n          }\n\n          //Option 2: Right child which doesnt have a left child\n        } else if (currentNode.right.left === null) {\n          currentNode.right.left = currentNode.left;\n          if (parentNode === null) {\n            this.root = currentNode.right;\n          } else {\n            //if parent \u003e current, make right child of the left the parent\n            if (currentNode.value \u003c parentNode.value) {\n              parentNode.left = currentNode.right;\n\n              //if parent \u003c current, make right child a right child of the parent\n            } else if (currentNode.value \u003e parentNode.value) {\n              parentNode.right = currentNode.right;\n            }\n          }\n\n          //Option 3: Right child that has a left child\n        } else {\n          //find the Right child's left most child\n          let leftmost = currentNode.right.left;\n          let leftmostParent = currentNode.right;\n          while (leftmost.left !== null) {\n            leftmostParent = leftmost;\n            leftmost = leftmost.left;\n          }\n\n          //Parent's left subtree is now leftmost's right subtree\n          leftmostParent.left = leftmost.right;\n          leftmost.left = currentNode.left;\n          leftmost.right = currentNode.right;\n\n          if (parentNode === null) {\n            this.root = leftmost;\n          } else {\n            if (currentNode.value \u003c parentNode.value) {\n              parentNode.left = leftmost;\n            } else if (currentNode.value \u003e parentNode.value) {\n              parentNode.right = leftmost;\n            }\n          }\n        }\n        return true;\n      }\n    }\n  }\n}\n\nconst tree = new BinarySearchTree();\ntree.insert(9);\ntree.insert(4);\ntree.insert(6);\ntree.insert(20);\ntree.insert(170);\ntree.insert(15);\ntree.insert(1);\ntree.lookup(11);\ntree.remove(170);\n\nconst traverse = (node) =\u003e {\n  const tree = { value: node.value };\n  tree.left = node.left === null ? null : traverse(node.left);\n  tree.right = node.right === null ? null : traverse(node.right);\n  return tree;\n};\n\ntraverse(tree.root);\n\n//     9\n//  4     20\n//1  6  15  170\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### [AVL Trees vs Red Black Trees](https://stackoverflow.com/questions/13852870/red-black-tree-over-avl-tree)\n\nAVL Trees\n\n- [Animation](https://www.cs.usfca.edu/~galles/visualization/AVLtree.html)\n- [How it Works](https://medium.com/basecs/the-little-avl-tree-that-could-86a3cae410c7)\n\nRed Black Trees:\n\n- [Animation](https://www.cs.usfca.edu/~galles/visualization/RedBlack.html)\n- [How it Works](https://medium.com/basecs/painting-nodes-black-with-red-black-trees-60eacb2be9a5)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Binary Heaps\n\n[Binary Heaps](https://visualgo.net/en/heap?slide=1)\n\n| Operation | Big O    |\n| --------- | -------- |\n| lookup    | O(n)     |\n| insert    | O(log n) |\n| delete    | O(log n) |\n\nReal life example - [Priority Queue](https://medium.com/@lucasmagnum/sidenotes-priority-queue-abstract-data-type-and-data-structure-52b5fcd7b904)\n\n- A real-life example of a [priority queue](https://medium.com/@lucasmagnum/sidenotes-priority-queue-abstract-data-type-and-data-structure-52b5fcd7b904) would be a hospital queue where the patient with the most critical situation would be the first in the queue. In this case, the priority order is the situation of each patient\n- [Implementation of Priority Queue in Javascript](https://www.geeksforgeeks.org/implementation-priority-queue-javascript/)\n\nPros\n\n- Better than O(n)\n- Priority\n- Flexible Size\n- Fast Insert\n\nCons\n\n- Slow Lookup\n\n**[⬆ back to top](#table-of-contents)**\n\n### Trie\n\nReal life example\n\n- auto complete your text\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 11: Data Structures: Graphs**\n\n### Types Of [Graphs](https://visualgo.net/en/graphds)\n\n- Directed - Twitter\n- Undirected - Facebook\n- Weighted - Shortest path\n- Unweighted\n- Cyclic - Google map\n- Acyclic\n- [Data Structures 101: Graphs — A Visual Introduction for Beginners](https://www.freecodecamp.org/news/data-structures-101-graphs-a-visual-introduction-for-beginners-6d88f36ec768/)\n\n[Real world examples](https://leapgraph.com/graph-data-structures-applications)\n\n- [The Internet map](https://internet-map.net/)\n- Facebook: Each user is represented as a vertex and two people are friends when there is an edge between two vertices. Similarly friend suggestion also uses graph theory concept.\n- Google Maps: Various locations are represented as vertices and the roads are represented as edges and graph theory is used to find shortest path between two nodes.\n- Recommendations on e-commerce websites: The “Recommendations for you” section on various e-commerce websites uses graph theory to recommend items of similar type to user’s choice.\n- Graph theory is also used to study molecules in chemistry and physics.\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Graph Implementation\n\n```javascript\nclass Graph { \n  constructor() { \n    this.numberOfNodes = 0; \n    this.adjacentList = {}; \n  } \n  addVertex(node)  { \n    this.adjacentList[node] = []; \n    this.numberOfNodes++;\n  } \n  addEdge(node1, node2) { \n    //uniderected Graph \n    this.adjacentList[node1].push(node2); \n    this.adjacentList[node2].push(node1); \n  } \n  showConnections() { \n    const allNodes = Object.keys(this.adjacentList); \n    for (let node of allNodes) { \n      let nodeConnections = this.adjacentList[node]; \n      let connections = \"\"; \n      let vertex;\n      for (vertex of nodeConnections) {\n        connections += vertex + \" \";\n      } \n      console.log(node + \"--\u003e\" + connections); \n    } \n  } \n} \n\nconst myGraph = new Graph();\nmyGraph.addVertex('0');\nmyGraph.addVertex('1');\nmyGraph.addVertex('2');\nmyGraph.addVertex('3');\nmyGraph.addVertex('4');\nmyGraph.addVertex('5');\nmyGraph.addVertex('6');\nmyGraph.addEdge('3', '1'); \nmyGraph.addEdge('3', '4'); \nmyGraph.addEdge('4', '2'); \nmyGraph.addEdge('4', '5'); \nmyGraph.addEdge('1', '2'); \nmyGraph.addEdge('1', '0'); \nmyGraph.addEdge('0', '2'); \nmyGraph.addEdge('6', '5');\nmyGraph\nmyGraph.showConnections(); \n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Graphs Review\n\n[neo4j](https://neo4j.com/)\n\nPro\n\n- Relationships\n\nCon\n\n- Scaling is hard\n\n**[⬆ back to top](#table-of-contents)**\n\n### Data Structures Review\n\n![](data-structures-blocks.jpg)\n\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 12: Algorithms: Recursion**\n\n### Introduction to Algorithms\n\n![](programs.jpg)\n\n| Data Structures | Data Structures |\n| --------------- | --------------- |\n| Arrays          | Queues          |\n| Hash tables     | Trees           |\n| Linked Lists    | Tries           |\n| Stacks          | Graphs          |\n\n\n| Algorithms            |\n| --------------------- |\n| Recursion             |\n| Sorting               |\n| BFS + DFS (Searching) |\n| Dynamic Programming   |\n\n**[⬆ back to top](#table-of-contents)**\n\n### Stack Overflow\n\n```javascript\nfunction inception() {\n  debugger;\n  inception();\n}\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Anatomy Of Recursion\n\n- Identify the base case\n- Identify the recursive case\n- Get closer and closer and return when needed. Usually you have 2 returns\n\n```javascript\nlet counter = 0;\n\nconst inception = () =\u003e {\n  console.log(counter)\n  // base case\n  if(counter \u003e 3) {\n    return 'done!';\n  }\n  counter++;\n  \n  // recursive calls\n  return inception();\n}\n\ninception();\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Factorial\n\n```javascript\n// Write two functions that finds the factorial of any number. One should use recursive, the other should just use a for loop\n\nconst findFactorialRecursive = number =\u003e {  // O(n)\n  if(number \u003c= 2) return number;\n  return number * findFactorialRecursive(number - 1);\n}\n\nconst findFactorialIterative = number =\u003e { // O(n)\n  let answer = 1;\n  for(let i = 2; i \u003c= number; i++)\n    answer = answer * i\n  return answer;\n}\n\nfindFactorialRecursive(5)\nfindFactorialIterative(5)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Fibonacci\n\n```javascript\n// Given a number N return the index value of the Fibonacci sequence, where the sequence is:\n\n// 0  1  2  3  4  5  6  7   8\n// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 ...\n// the pattern of the sequence is that each value is the sum of the 2 previous values, that means that for N=5 → 2+3\n\n//For example: fibonacciRecursive(6) should return 8\n\nconst fibonacciIterative = n =\u003e {\n  const arr = [0, 1];\n  for (let i = 2; i \u003c= n; i++){\n    arr.push(arr[i - 2] + arr[i -1]);\n  }\n return arr[n];\n}\nfibonacciIterative(3);\n\nconst fibonacciRecursive = n =\u003e {\n  if(n \u003c= 1) return n; \n  return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);\n}\nfibonacciRecursive(6)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Recursive VS Iterative\n\nAnything you do with a recursion can be done iteratively (loop)\n\nRecursion\n\nPros\n\n- DRY\n- Readability\n\nCons\n\n- Large Stack\n\n[Tail call optimization in ECMAScript 6](https://2ality.com/2015/06/tail-call-optimization.html)\n\n**[⬆ back to top](#table-of-contents)**\n\n### When To Use Recursion\n\n[Real-world examples of recursion](https://stackoverflow.com/questions/105838/real-world-examples-of-recursion)\n\nEvery time you are using a tree or converting something into a tree, consider recursion\n\n- Divided into a number of subproblems that are smaller instances of the same problem\n- Each instance of the subproblem is identical in nature\n- The solutions of each subproblem can be combined to solve the problem at hand.\n\nDivide and Conquer using Recursion\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Reverse String With Recursion\n\n```javascript\n//Implement a function that reverses a string using iteration...and then recursion!\nconst reverseString = str =\u003e str.split('').reverse().join('');\nreverseString('yoyo mastery')\n\nconst reverseStringRecursive = str =\u003e {\n  if(str.length === 1) return str;\n  return reverseStringRecursive(str.substring(1)).concat(str[0]);\n}\nreverseStringRecursive('yoyo mastery')\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Recursion Review\n\n- Merge Sort\n- Quick Sort\n- Tree Traversal\n- Graph Traversal\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 13: Algorithms: Sorting**\n\n### Sorting Introduction\n\n- Bubble Sort\n- Insertion Sort\n- Selection Sort\n- Merge Sort\n- Quick Sort\n\n**[⬆ back to top](#table-of-contents)**\n\n### The Issue With sort()\n\n```javascript\n// default sort order is ascending\n// converting the elements into strings\n// then comparing their sequences of UTF-16 code units values\nconst months = ['March', 'Jan', 'Feb', 'Dec'];\nmonths.sort();\nconsole.log(months);\n// expected output: Array [\"Dec\", \"Feb\", \"Jan\", \"March\"]\n\nconst array1 = [1, 30, 4, 21, 100000];\narray1.sort();\nconsole.log(array1);\n// expected output: Array [1, 100000, 21, 30, 4]\n```\n**[⬆ back to top](#table-of-contents)**\n\n###  Sorting Algorithms\n\n[Sorting Algorithms Animations](https://www.toptal.com/developers/sorting-algorithms)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Bubble Sort\n\n```javascript\nconst numbers = [99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0];\n\nconst bubbleSort = array =\u003e {\n  const length = array.length;\n  for (let i = 0; i \u003c length; i++) {\n    for (let j = 0; j \u003c length; j++) { \n      if(array[j] \u003e array[j+1]) {\n        [array[j], array[j+1]] = [array[j+1], array[j]];\n      }\n      console.log(array)\n    }        \n  }\n}\n\nbubbleSort(numbers);\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Selection Sort\n\n```javascript\nconst numbers = [99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0];\n\nconst selectionSort = array =\u003e {\n  const length = array.length;\n  for (let i = 0; i \u003c length; i++) {\n    let min = i;\n    for (let j = i + 1; j \u003c length; j++) {\n      if (array[min] \u003e array[j]) {\n          min = j;\n      }\n    }\n    if (min !== i) {\n      [array[i], array[min]] = [array[min], array[i]]\n    }\n  }\n  return array;\n}\n\nselectionSort(numbers);\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Dancing Algorithms\n\n[AlgoRythmics](https://www.youtube.com/user/AlgoRythmics/videos)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Insertion Sort\n\n```javascript\nconst numbers = [99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0];\n\nconst insertionSort = array =\u003e {\n  for (let i = 1; i \u003c array.length; i++) {\n    let j = i - 1\n    let tmp = array[i]\n    while (j \u003e= 0 \u0026\u0026 array[j] \u003e tmp) {\n      array[j + 1] = array[j]\n      j--\n    }\n    array[j+1] = tmp\n  }\n  return array\n}\n\ninsertionSort(numbers);\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### O(n log n)\n\nDivide \u0026 Conquer\n\n- Merge Sort\n- Quick Sort\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Merge Sort\n\n```javascript\nconst numbers = [99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0];\n\nconst mergeSort = array =\u003e {\n  // base case\n  if (array.length === 1) {\n    return array\n  }\n  // Split Array in into right and left\n  const length = array.length;\n  const middle = Math.floor(length / 2)\n  const left = array.slice(0, middle) \n  const right = array.slice(middle)\n\n  return merge(\n    mergeSort(left),\n    mergeSort(right)\n  )\n}\n\nconst merge = (left, right) =\u003e {\n  const result = [];\n  let leftIndex = 0;\n  let rightIndex = 0;\n  while(leftIndex \u003c left.length \u0026\u0026 rightIndex \u003c right.length){\n    if(left[leftIndex] \u003c right[rightIndex]){\n      result.push(left[leftIndex]);\n      leftIndex++;\n    } else{\n      result.push(right[rightIndex]);\n      rightIndex++\n    }\n  }  \n  return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));\n}\n\nconst answer = mergeSort(numbers);\n```\n\n**[⬆ back to top](#table-of-contents)**\n\nStable VS Unstable Algorithms\n\n[What is stability in sorting algorithms and why is it important?](https://stackoverflow.com/questions/1517793/what-is-stability-in-sorting-algorithms-and-why-is-it-important)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Quick Sort\n\n```javascript\nconst numbers = [99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0];\n\nconst swap = (array, a, b) =\u003e [array[a], array[b]] = [array[b], array[a]];\nconst partition = (array, pivot, left, right) =\u003e {\n  let pivotValue = array[pivot];\n  let partitionIndex = left;\n\n  for(let i = left; i \u003c right; i++) {\n    if(array[i] \u003c pivotValue){\n      swap(array, i, partitionIndex);\n      partitionIndex++;\n    }\n  }\n  swap(array, right, partitionIndex);\n  return partitionIndex;\n}\n\nconst quickSort = (array, left = 0, right = array.length - 1) =\u003e {\n  let pivot;\n  let partitionIndex;\n\n  if(left \u003c right) {\n    pivot = right;\n    partitionIndex = partition(array, pivot, left, right);\n    \n    //sort left and right\n    quickSort(array, left, partitionIndex - 1);\n    quickSort(array, partitionIndex + 1, right);\n  }\n  return array;\n}\n\nquickSort(numbers);\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Which Sort Is Best?\n\n![](array-sorting-algorithms.jpg)\n\n[Criteria for Choosing a Sorting Algorithm](https://learning.oreilly.com/library/view/algorithms-in-a/9780596516246/ch04s09.html)\n\n| Criteria                                   | Sorting algorithm |\n| ------------------------------------------ | ----------------- |\n| Only a few items                           | Insertion Sort    |\n| Items are mostly sorted already            | Insertion Sort    |\n| Concerned about worst-case scenarios       | Heap Sort         |\n| Interested in a good average-case result   | Quicksort         |\n| Items are drawn from a dense universe      | Bucket Sort       |\n| Desire to write as little code as possible | Insertion Sort    |\n\n**[⬆ back to top](#table-of-contents)**\n\n### Heap Sort\n\n```javascript\nconst swap = (array, a, b) =\u003e [array[a], array[b]] = [array[b], array[a]];\n\nconst max_heapify = (array, i, length) =\u003e {\n  while (true) {\n    let left = i*2 + 1;\n    let right = i*2 + 2;\n    let largest = i;\n\n    if (left \u003c length \u0026\u0026 array[left] \u003e array[largest]) {\n        largest = left;\n    }\n\n    if (right \u003c length \u0026\u0026 array[right] \u003e array[largest]) {\n        largest = right;\n    }\n\n    if (i == largest) {\n        break;\n    }\n\n    swap(array, i, largest);\n    i = largest;\n  }\n}\n\nconst heapify = (array, length) =\u003e {\n  for (let i = Math.floor(length/2); i \u003e= 0; i--) {\n    max_heapify(array, i, length);\n  }\n}\n\nconst heapsort = array =\u003e {\n  heapify(array, array.length);\n\n  for (let i = array.length - 1; i \u003e 0; i--) {\n    swap(array, i, 0);\n    max_heapify(array, 0, i-1);\n  }\n}\n\nconst numbers = [99, 44, 6, 2, 1, 5, 63, 87, 283, 4, 0];\nheapsort(numbers);\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Radix Sort + Counting Sort\n\nCan we beat O(nlogn)?\n\n| Comparison Sort | Non-Comparison Sort |\n| --------------- | ------------------- |\n| Bubble Sort     | Counting Sort       |\n| Insertion Sort  | Radix Sort          |\n| Selection Sort  |                     |\n| Merge Sort      |                     |\n| Quick Sort      |                     |\n\n- [Radix Sort](https://brilliant.org/wiki/radix-sort/)\n- [Radix Sort Animation](https://www.cs.usfca.edu/~galles/visualization/RadixSort.html)\n- [Counting Sort](https://brilliant.org/wiki/counting-sort/) \n- [Counting Sort Animation](https://www.cs.usfca.edu/~galles/visualization/CountingSort.html)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Sorting Interview\n\n| Question                                                                                 | Sorting algorithm                                    |\n| ---------------------------------------------------------------------------------------- | ---------------------------------------------------- |\n| Sort 10 schools around your house by distance                                            | Insertion Sort                                       |\n| eBay sorts listings by the current Bid amount                                            | Radix or Counting sort                               |\n| Sort scores on ESPN                                                                      | Quick sort                                           |\n| Massive database (can't fit all into memory) needs to sort through past year's user data | Merge Sort                                           |\n| Almost sorted Udemy review data needs to update and add 2 new reviews                    | Insertion Sort                                       |\n| Temperature Records for the past 50 years in Canada                                      | radix or counting Sort, Quick sort if decimal places |\n| Large user name database needs to be sorted. Data is very random.                        | Quick sort                                           |\n| You want to teach sorting                                                                | Bubble sort                                          |\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 14: Algorithms: Searching + BFS + DFS**\n\n### Searching + Traversal Introduction\n\n- Linear Search\n- Binary Search\n- Depth First Search\n- Breadth First Search\n\n**[⬆ back to top](#table-of-contents)**\n\n### Linear Search\n\n```javascript\nconst beasts = ['Centaur', 'Godzilla', 'Mosura', 'Minotaur', 'Hydra', 'Nessie'];\n\nbeasts.indexOf('Godzilla'); // O(n)\nbeasts.findIndex(item =\u003e item === 'Godzilla');  // O(n)\nbeasts.find(item =\u003e item === 'Godzilla'); // O(n)\nbeasts.includes('Godzilla'); // O(n)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Binary Search\n\n```javascript\nconst binarySearch = (array, x, start = 0, end = array.length-1) =\u003e { \n\n  // Base Condition \n  if (start \u003e end) return false; \n  \n  // Find the middle index \n  let mid=Math.floor((start + end)/2); \n  \n  // Compare mid with given key x \n  if (array[mid]===x) return true; \n\n  // If element at mid is greater than x, \n  // search in the left half of mid \n  if(array[mid] \u003e x)  \n    return binarySearch(array, x, start, mid-1); \n  else\n    // If element at mid is smaller than x, \n    // search in the right half of mid \n    return binarySearch(array, x, mid+1, end); \n}\n\nconst numbers = [1, 3, 5, 7, 8, 9]; \nbinarySearch(numbers, 5, 0, numbers.length-1)\nbinarySearch(numbers, 6, 0, numbers.length-1)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### BFS vs DFS\n\n[What is the time and space complexity of a breadth first and depth first tree traversal?](https://stackoverflow.com/questions/9844193/what-is-the-time-and-space-complexity-of-a-breadth-first-and-depth-first-tree-tr)\n\n```\n//     9\n//  4     20\n//1  6  15  170\n// BFS - [9, 4, 20, 1, 6, 15, 170]\n// DFS - [9, 4, 1, 6, 20, 15, 170]\n```\n\nBFS\n\n| Pros          | Cons        |\n| ------------- | ----------- |\n| Shortest Path | More Memory |\n| Closer Nodes  |             |\n\nDFS\n\n| Pros         | Cons              |\n| ------------ | ----------------- |\n| Less Memory  | Does Path Exists? |\n| Can Get Slow |                   |\n\n| Question                                                    | BFS or DFS                          |\n| ----------------------------------------------------------- | ----------------------------------- |\n| If you know a solution is not far from the root of the tree | Does Path Exists?                   |\n| If the tree is very deep and solutions are rare             | BFS (DFS will take long time)       |\n| If the tree is very wide                                    | DFS (BFS will need too much memory) |\n| If solutions are frequent but located deep in the tree      | DFS                                 |\n| determining whether a path exists between two nodes         | DFS                                 |\n| Finding the shortest path                                   | BFS                                 |\n\n**[⬆ back to top](#table-of-contents)**\n\n### breadthFirstSearch()\n\n```javascript\nclass Node {\n  constructor(value){\n    this.left = null;\n    this.right = null;\n    this.value = value;\n  }\n}\n\nclass BinarySearchTree {\n  constructor(){\n    this.root = null;\n  }\n  insert(value){\n    const newNode = new Node(value);\n    if (this.root === null) {\n      this.root = newNode;\n    } else {\n      let currentNode = this.root;\n      while(true){\n        if(value \u003c currentNode.value){\n          //Left\n          if(!currentNode.left){\n            currentNode.left = newNode;\n            return this;\n          }\n          currentNode = currentNode.left;\n        } else {\n          //Right\n          if(!currentNode.right){\n            currentNode.right = newNode;\n            return this;\n          } \n          currentNode = currentNode.right;\n        }\n      }\n    }\n  }\n  lookup(value){\n    if (!this.root) {\n      return false;\n    }\n    let currentNode = this.root;\n    while(currentNode){\n      if(value \u003c currentNode.value){\n        currentNode = currentNode.left;\n      } else if(value \u003e currentNode.value){\n        currentNode = currentNode.right;\n      } else if (currentNode.value === value) {\n        return currentNode;\n      }\n    }\n    return null\n  }\n  remove(value) {\n    if (!this.root) {\n      return false;\n    }\n    let currentNode = this.root;\n    let parentNode = null;\n    while(currentNode){\n      if(value \u003c currentNode.value){\n        parentNode = currentNode;\n        currentNode = currentNode.left;\n      } else if(value \u003e currentNode.value){\n        parentNode = currentNode;\n        currentNode = currentNode.right;\n      } else if (currentNode.value === value) {\n        //We have a match, get to work!\n        \n        //Option 1: No right child: \n        if (currentNode.right === null) {\n          if (parentNode === null) {\n            this.root = currentNode.left;\n          } else {\n            \n            //if parent \u003e current value, make current left child a child of parent\n            if(currentNode.value \u003c parentNode.value) {\n              parentNode.left = currentNode.left;\n            \n            //if parent \u003c current value, make left child a right child of parent\n            } else if(currentNode.value \u003e parentNode.value) {\n              parentNode.right = currentNode.left;\n            }\n          }\n        \n        //Option 2: Right child which doesnt have a left child\n        } else if (currentNode.right.left === null) {\n          if(parentNode === null) {\n            this.root = currentNode.left;\n          } else {\n            currentNode.right.left = currentNode.left;\n            \n            //if parent \u003e current, make right child of the left the parent\n            if(currentNode.value \u003c parentNode.value) {\n              parentNode.left = currentNode.right;\n            \n            //if parent \u003c current, make right child a right child of the parent\n            } else if (currentNode.value \u003e parentNode.value) {\n              parentNode.right = currentNode.right;\n            }\n          }\n        \n        //Option 3: Right child that has a left child\n        } else {\n\n          //find the Right child's left most child\n          let leftmost = currentNode.right.left;\n          let leftmostParent = currentNode.right;\n          while(leftmost.left !== null) {\n            leftmostParent = leftmost;\n            leftmost = leftmost.left;\n          }\n          \n          //Parent's left subtree is now leftmost's right subtree\n          leftmostParent.left = leftmost.right;\n          leftmost.left = currentNode.left;\n          leftmost.right = currentNode.right;\n\n          if(parentNode === null) {\n            this.root = leftmost;\n          } else {\n            if(currentNode.value \u003c parentNode.value) {\n              parentNode.left = leftmost;\n            } else if(currentNode.value \u003e parentNode.value) {\n              parentNode.right = leftmost;\n            }\n          }\n        }\n      return true;\n      }\n    }\n  }\n  BreadthFirstSearch(){\n    let currentNode = this.root;\n    let list = [];\n    let queue = [];\n    queue.push(currentNode);\n\n    while(queue.length \u003e 0){\n      currentNode = queue.shift();\n      list.push(currentNode.value);\n      if(currentNode.left) {\n        queue.push(currentNode.left);\n      }\n      if(currentNode.right) {\n        queue.push(currentNode.right);\n      }\n    }\n    return list;\n  }\n  BreadthFirstSearchR(queue, list) {\n    if (!queue.length) {\n      return list;\n    }\n    const currentNode = queue.shift();\n    list.push(currentNode.value);\n    \n    if (currentNode.left) {\n      queue.push(currentNode.left);\n    }\n    if (currentNode.right) {\n      queue.push(currentNode.right);\n    }\n    return this.BreadthFirstSearchR(queue, list);\n  }\n}\n\nconst tree = new BinarySearchTree();\ntree.insert(9)\ntree.insert(4)\ntree.insert(6)\ntree.insert(20)\ntree.insert(170)\ntree.insert(15)\ntree.insert(1)\n\ntree.BreadthFirstSearch()\ntree.BreadthFirstSearchR([tree.root], [])\n\n//     9\n//  4     20\n//1  6  15  170\n// BFS - [9, 4, 20, 1, 6, 15, 170]\n```\n**[⬆ back to top](#table-of-contents)**\n\n### PreOrder, InOrder, PostOrder\n\n```javascript\nIn Order - left, root, right\nIn Order - [1, 4, 6, 9, 15, 20, 170]\n\nPre Order - root, left, right (use to re-create the tree)\nPre Order - [9, 4, 1, 6, 20, 15, 170]\n\nPost Order - left, right, root\nPost Order - [1, 6, 4, 15, 170, 20, 9]\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### depthFirstSearch()\n\n```javascript\nclass Node {\n  constructor(value){\n    this.left = null;\n    this.right = null;\n    this.value = value;\n  }\n}\n\nclass BinarySearchTree {\n  constructor(){\n    this.root = null;\n  }\n  insert(value){\n    const newNode = new Node(value);\n    if (this.root === null) {\n      this.root = newNode;\n    } else {\n      let currentNode = this.root;\n      while(true){\n        if(value \u003c currentNode.value){\n          //Left\n          if(!currentNode.left){\n            currentNode.left = newNode;\n            return this;\n          }\n          currentNode = currentNode.left;\n        } else {\n          //Right\n          if(!currentNode.right){\n            currentNode.right = newNode;\n            return this;\n          } \n          currentNode = currentNode.right;\n        }\n      }\n    }\n  }\n  lookup(value){\n    if (!this.root) {\n      return false;\n    }\n    let currentNode = this.root;\n    while(currentNode){\n      if(value \u003c currentNode.value){\n        currentNode = currentNode.left;\n      } else if(value \u003e currentNode.value){\n        currentNode = currentNode.right;\n      } else if (currentNode.value === value) {\n        return currentNode;\n      }\n    }\n    return null\n  }\n  remove(value) {\n    if (!this.root) {\n      return false;\n    }\n    let currentNode = this.root;\n    let parentNode = null;\n    while(currentNode){\n      if(value \u003c currentNode.value){\n        parentNode = currentNode;\n        currentNode = currentNode.left;\n      } else if(value \u003e currentNode.value){\n        parentNode = currentNode;\n        currentNode = currentNode.right;\n      } else if (currentNode.value === value) {\n        //We have a match, get to work!\n        \n        //Option 1: No right child: \n        if (currentNode.right === null) {\n          if (parentNode === null) {\n            this.root = currentNode.left;\n          } else {\n            \n            //if parent \u003e current value, make current left child a child of parent\n            if(currentNode.value \u003c parentNode.value) {\n              parentNode.left = currentNode.left;\n            \n            //if parent \u003c current value, make left child a right child of parent\n            } else if(currentNode.value \u003e parentNode.value) {\n              parentNode.right = currentNode.left;\n            }\n          }\n        \n        //Option 2: Right child which doesnt have a left child\n        } else if (currentNode.right.left === null) {\n          if(parentNode === null) {\n            this.root = currentNode.left;\n          } else {\n            currentNode.right.left = currentNode.left;\n            \n            //if parent \u003e current, make right child of the left the parent\n            if(currentNode.value \u003c parentNode.value) {\n              parentNode.left = currentNode.right;\n            \n            //if parent \u003c current, make right child a right child of the parent\n            } else if (currentNode.value \u003e parentNode.value) {\n              parentNode.right = currentNode.right;\n            }\n          }\n        \n        //Option 3: Right child that has a left child\n        } else {\n\n          //find the Right child's left most child\n          let leftmost = currentNode.right.left;\n          let leftmostParent = currentNode.right;\n          while(leftmost.left !== null) {\n            leftmostParent = leftmost;\n            leftmost = leftmost.left;\n          }\n          \n          //Parent's left subtree is now leftmost's right subtree\n          leftmostParent.left = leftmost.right;\n          leftmost.left = currentNode.left;\n          leftmost.right = currentNode.right;\n\n          if(parentNode === null) {\n            this.root = leftmost;\n          } else {\n            if(currentNode.value \u003c parentNode.value) {\n              parentNode.left = leftmost;\n            } else if(currentNode.value \u003e parentNode.value) {\n              parentNode.right = leftmost;\n            }\n          }\n        }\n      return true;\n      }\n    }\n  }\n  DFTPreOrder(currentNode, list) {\n    return traversePreOrder(this.root, []);\n  }\n  DFTPostOrder(){\n    return traversePostOrder(this.root, []); \n  }\n  DFTInOrder(){\n    return traverseInOrder(this.root, []);\n  } \n}\n\nconst traversePreOrder = (node, list) =\u003e {\n  list.push(node.value);\n  if(node.left) {\n    traversePreOrder(node.left, list);\n  }\n  if(node.right) {\n    traversePreOrder(node.right, list);\n  }\n  return list;\n}\n\nconst traverseInOrder = (node, list) =\u003e {\n  if(node.left) {\n    traverseInOrder(node.left, list);\n  }\n  list.push(node.value);\n  if(node.right) {\n    traverseInOrder(node.right, list);\n  }\n  return list;\n}\n\nconst traversePostOrder = (node, list) =\u003e {\n  if(node.left) {\n    traversePostOrder(node.left, list);\n  }\n  if(node.right) {\n    traversePostOrder(node.right, list);\n  }\n  list.push(node.value);\n  return list;\n}\n\nconst tree = new BinarySearchTree();\ntree.insert(9)\ntree.insert(4)\ntree.insert(6)\ntree.insert(20)\ntree.insert(170)\ntree.insert(15)\ntree.insert(1)\n\ntree.DFTPreOrder();\ntree.DFTInOrder();\ntree.DFTPostOrder();\n\n//     9\n//  4     20\n//1  6  15  170\n// In Order - left, root, right\n// In Order - [1, 4, 6, 9, 15, 20, 170]\n\n// Pre Order - root, left, right (use to re-create the tree)\n// Pre Order - [9, 4, 1, 6, 20, 15, 170]\n\n// Post Order - left, right, root\n// Post Order - [1, 6, 4, 15, 170, 20, 9]\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Exercise: Validate A BST\n\n[Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/)\n\n**[⬆ back to top](#table-of-contents)**\n\n### Graph Traversals\n\n- Breadth First Search - Shortest path\n- Depth First Search - Check to see if it exists\n\nBFS\n\n| Pros          | Cons        |\n| ------------- | ----------- |\n| Shortest Path | More Memory |\n| Closer Nodes  |             |\n\nDFS\n\n| Pros         | Cons              |\n| ------------ | ----------------- |\n| Less Memory  | Does Path Exists? |\n| Can Get Slow |                   |\n\n**[⬆ back to top](#table-of-contents)**\n\n### Dijkstra + Bellman-Ford Algorithms\n\n[Finding The Shortest Path, With A Little Help From Dijkstra](https://medium.com/basecs/finding-the-shortest-path-with-a-little-help-from-dijkstra-613149fbdc8e)\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 15: Algorithms: Dynamic Programming**\n\n### Dynamic Programming Introduction\n\n- It is an optimization technique\n- Do you have something you can cache? Dynamic Programming\n- Dynamic Programming = Divide \u0026 Conquer + Memorization\n\nWhen to use Dynamic Programming?\n\n- Can be divided into subproblem\n- Recursion Solution\n- Are there repetitive subproblems?\n- Memorize subproblems\n\n**[⬆ back to top](#table-of-contents)**\n\n### Memoization\n\nOptimization - Caching\n\n**[⬆ back to top](#table-of-contents)**\n\n### Memoization\n\n```javascript\nconst addTo80 = n =\u003e n + 80;\naddTo80(5)\naddTo80(5)\naddTo80(5)\n\n//learn to cache\nlet cache = {};\nconst memoizeAddTo80 = n =\u003e {\n  if (n in cache) {\n    return cache[n];\n  } else {\n    console.log('long time');\n    const answer = n + 80;\n    cache[n] = answer;\n    return answer;\n  }\n}\nmemoizeAddTo80(5)\nmemoizeAddTo80(5)\nmemoizeAddTo80(5)\n\n// let's make that better with no global scope\n// This is closure in javascript\nconst memoizeAddTo80Closure = n =\u003e { \n  const cache = {};\n  return n =\u003e {\n    if (n in cache) {\n      return cache[n];\n    } else {\n      console.log('long time');\n      const answer = n + 80;\n      cache[n] = answer;\n      return answer;\n    }\n  }\n}\n\nconst memoized = memoizeAddTo80Closure();\nmemoized(5)\nmemoized(5)\nmemoized(5)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Fibonacci and Dynamic Programming\n\n```javascript\n//0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233...\nlet calculations = 0;\nconst fibonacci = n =\u003e { //O(2^n)\n  calculations++;\n  if (n \u003c 2) {\n    return n\n  }\n  return fibonacci(n-1) + fibonacci(n-2);\n}\nfibonacci(10)\ncalculations\n\ncalculations = 0\nconst fibonacciMaster = () =\u003e { //O(n)\n  let cache = {};\n  return function fib(n) {\n    calculations++;\n    if (n in cache) {\n      return cache[n];\n    } else {\n      if (n \u003c 2) {\n        return n;\n      } else {\n        cache[n] = fib(n-1) + fib(n-2);\n        return cache[n];\n      }\n    }\n  }\n}\nconst fasterFib = fibonacciMaster();\nfasterFib(10)\ncalculations\n\nconst fibonacciMaster2 = n =\u003e {\n  let answer = [0, 1];\n  for ( let i = 2; i \u003c= n; i++) {\n    answer.push(answer[i-2]+ answer[i-1]);\n  }\n  return answer.pop();\n}\nfibonacciMaster2(10)\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n### Interview Questions: Dynamic Programming\n\n- [House Robber](https://leetcode.com/problems/house-robber/) \n- [Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/)\n- [Climbing Stairs](https://leetcode.com/problems/climbing-stairs/)\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 16: Non Technical Interviews**\n\n### Section Overview\n\n- Tell me about a problem you solved?\n- Why do you want to work for us?\n- What to ask the Interviewer?\n- Tell me about yourself?\n- What is your biggest weaknes?\n- Secret Weapon\n\n**[⬆ back to top](#table-of-contents)**\n\n### During The Interview\n\nMindset\n\n- Treat everything as a learning experience.\n- Walking in to meet a best friend and try to make the interviewers day\n\n3 Questions\n\n- Can you do the job?\n- Can I work with you?\n- Are you going to improve?\n\n4 Heros\n\n- Technical\n- Success\n- Leadership\n- Challenge\n\n**[⬆ back to top](#table-of-contents)**\n\n### Tell Me About Yourself (1 min)\n\n- Your triggers of success\n- Mention things you want to get asked\n- Skills should be relevant to job\n\nMy story\n\n- Challenge\n- Technical\n- Success\n\n**[⬆ back to top](#table-of-contents)**\n\n### Why Us?\n\n- Show you want to grow\n- Demonstrate why you are the best\n\nWhy did you leave your job?\n\n- No negativity\n\n**[⬆ back to top](#table-of-contents)**\n\n### Tell Me About A Problem You Have Solved\n\n- Have this prepared\n- Have metrics and numbers\n- Scaling, performance, security\n\nSAR method\n\n- Situation\n- Action\n- Result\n\nTell me about an interesting project?\n\n- Show how you are different\n- Relate it to this job\n\n**[⬆ back to top](#table-of-contents)**\n\n### What Is Your Biggest Weakness\n\n- Real answer\n- Show how you improved it\n\n**[⬆ back to top](#table-of-contents)**\n\n### Any Questions For Us?\n\n[Reverse interview](https://github.com/viraptor/reverse-interview)\n\n- Focus on them, not company (YOU)\n- Mention something they mentioned\n\n**[⬆ back to top](#table-of-contents)**\n\n### Secret Weapon\n\n- Simplicity over complexity\n- Premature Optimization is the root of all evil\n- Focus on overall goal and not be myopic\n- No complaining about client/code/etc\n- No ego\n\n**[⬆ back to top](#table-of-contents)**\n\n### After The Interview\n\n- Don't overuse \"I\"\n- Talk about the interviewr\n- Express how you are ideal candidate\n- Don't brag\n\n**[⬆ back to top](#table-of-contents)**\n\n### Section Summary\n\n- Have a good mindset\n- Bring the energy and have a two way conversation with them\n- And when you leave the interview in the final minutes also and on a strong note have a strong closing argument of why they should hire you\n- 4 Heroes: Technical, Success, Leadership, Challenge\n- If I hire you will you make my life easier.\n  - Can you speak to people on your team?\n  - Can you communicate with clients and customers and coworkers?\n  - Are you able to focus on prioritizing tasks and not getting stuck solving a problem?\n  - Do you need hand-holding or you're able to be independent and solve problems on your own?\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 17: Offer + Negotiation**\n\n### Negotiation 101\n\n- Don't end the conversation\n- Give reason for everything\n- Always negotiate\n- Be positive\n- Have stakes\n\n**[⬆ back to top](#table-of-contents)**\n\n### Handling An Offer\n\n- Don't end the conversation\n- Be positive\n- Ask for time\n- Let other companies know\n\nTo Do\n\n- Find exact salary you want\n  - [Salary.com](https://www.salary.com/)\n  - [Glassdoor](https://www.glassdoor.sg/index.htm?countryRedirect=true)\n  - [PayScale](https://www.payscale.com/)\n- What value do you provide?\n- Go higher\n\n**[⬆ back to top](#table-of-contents)**\n\n### Handling Multiple Offers\n\n- Is there an offer that you feel you are under qualified for?\n- Long term growth potential\n- Will you respect people around you?\n- Salary and benefits?\n- Is your decision based on desperation?\n\n**[⬆ back to top](#table-of-contents)**\n\n### Getting A Raise\n\n- Ask for a raise\n- Show. Don't tell\n\n**[⬆ back to top](#table-of-contents)**\n\n### Negotiation Master\n\n- [StackOverflow Developer Salary](https://stackoverflow.com/jobs/salary?utm_source=Iterable\u0026utm_medium=email\u0026utm_campaign=salary-calculator-2018)\n- [How to Negotiate Your Salary](https://www.youtube.com/watch?v=XY5SeCl_8NE\u0026feature=youtu.be)\n\n**[⬆ back to top](#table-of-contents)**\n\n## **Section 19: Extras: Google, Amazon, Facebook Interview Questions**\n\n- [Top Interview Questions](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/learn/lecture/12246878#content)\n- [Amazon Interview Questions](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/learn/lecture/12246840#content)\n- [Facebook Interview Questions](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/learn/lecture/12246842#content)\n- [Google Interview Questions](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/learn/lecture/12246838#content)\n- [Domain Specific Questions](https://www.udemy.com/course/master-the-coding-interview-data-structures-algorithms/learn/lecture/12246846#content)\n   \n**[⬆ back to top](#table-of-contents)**\n","funding_links":[],"categories":["Others"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchesterheng%2Fmaster-coding-interview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchesterheng%2Fmaster-coding-interview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchesterheng%2Fmaster-coding-interview/lists"}