diff --git a/.assets/dsa.jpeg b/.assets/dsa.jpeg new file mode 100644 index 00000000..2b9440ab Binary files /dev/null and b/.assets/dsa.jpeg differ diff --git a/.assets/logo.png b/.assets/logo.png new file mode 100644 index 00000000..bd744de1 Binary files /dev/null and b/.assets/logo.png differ diff --git a/README.md b/README.md index 1b1e130c..01dfd851 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + # Problem Solving using Javascript [![Open Source Love](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/vinitshahdeo/HacktoberFest) @@ -7,17 +9,20 @@ Collection of interview questions with Unit Tests. Problems includes Data Structures, Logical and few Classical problems. -## Table of Contents +![DSA](.assets/dsa.jpeg) + +## Overview + +This repo contains the following sections implemented in **JavaScript** -This repo contains the following in **JavaScript** -- Data Structures -- Algorithms -- Logical Problems -- Classics (Few of the classical questions) +- [Data Structures](src/_DataStructures_) +- [Algorithms](src/_Algorithms_) +- [Logical Problems](src/_Problems_) +- [Classics (Few of the classical questions)](src/_Classics_) -Find the detailed Table of Contents here: [Detailed TOC](TOC.md) +Find the detailed contents and problem list here: [Table Of Contents](TOC.md) -## CONTRIBUTION Guide +## Contribution Guide It's great to know that you want to contribute to this repo. Thanks for taking interest. please fing the [guide here](https://github.com/knaxus/problem-solving-javascript/blob/master/CONTRIBUTING.md) diff --git a/TOC.md b/TOC.md index e19354ef..8bcc7ec6 100644 --- a/TOC.md +++ b/TOC.md @@ -1,4 +1,3 @@ - ## Table of Contents ### Data Structures @@ -44,6 +43,12 @@ - [Unique words count in a Trie](src/_DataStructures_/Trees/Trie/unique-word-count) - [All the words from a Trie](src/_DataStructures_/Trees/Trie/all-words-in-trie) - [Unique words in a Trie](src/_DataStructures_/Trees/Trie/get-unique-words) +- [Heaps](src/_DataStructures_/Heaps) + - [MaxHeap](src/_DataStructures_/Heaps/MaxHeap) + - [MinHeap](src/_DataStructures_/Heaps/MinHeap) + - Problems + - [K Largest Elements](src/_DataStructures_/Heaps/k-largest-in-array) + - [K Smallest Elements](src/_DataStructures_/Heaps/k-smallest-in-array) ### Logical Problems @@ -75,8 +80,7 @@ - [LRU Cache](src/_Algorithms_/lru-cache) - Path Finders - - [A*](src/_Algorithms_/path-finder/a-star) - + - [A\*](src/_Algorithms_/path-finder/a-star) ### Classics diff --git a/src/_DataStructures_/Heaps/MaxHeap/MaxHeap.test.js b/src/_DataStructures_/Heaps/MaxHeap/MaxHeap.test.js index 181390ed..5fee6e35 100644 --- a/src/_DataStructures_/Heaps/MaxHeap/MaxHeap.test.js +++ b/src/_DataStructures_/Heaps/MaxHeap/MaxHeap.test.js @@ -15,6 +15,11 @@ describe('MaxHeap', () => { expect(mh instanceof MaxHeap).toEqual(true); }); + it('Should create a MaxHeap using collection', () => { + const mHBulk = new MaxHeap([1, 3, 21, 9, 101, 0]); + expect(mHBulk.getMax()).toEqual(101); + }); + it('Should add an element to the MaxHeap', () => { mh.add(10); expect(mh.getMax()).toEqual(10); @@ -47,4 +52,8 @@ describe('MaxHeap', () => { expect(mh.remove()).toEqual(1); expect(mh.getMax()).toEqual(null); }); + + it('Should return `null` on `remove() called on empty heap`', () => { + expect(mh.getMax()).toEqual(null); + }); }); diff --git a/src/_DataStructures_/Heaps/MaxHeap/index.js b/src/_DataStructures_/Heaps/MaxHeap/index.js index bf94e9d6..81dcdb97 100644 --- a/src/_DataStructures_/Heaps/MaxHeap/index.js +++ b/src/_DataStructures_/Heaps/MaxHeap/index.js @@ -1,6 +1,11 @@ class MaxHeap { - constructor() { + constructor(collection) { this.heap = []; + if (collection) { + collection.forEach((element) => { + this.add(element); + }); + } } add(element) { @@ -11,27 +16,24 @@ class MaxHeap { } getMax() { - return this.heap[0] || null; + return this.heap[0] !== undefined ? this.heap[0] : null; } remove() { + const max = this.heap[0] !== undefined ? this.heap[0] : null; // return the element at the root - const max = this.heap[0] || null; + if (this.heap.length === 1) { + this.heap.pop(); + } + if (this.heap.length> 1) { // move the leaf to the root this.heap[0] = this.heap[this.heap.length - 1]; - this.heap.splice(this.heap.length - 1, 1); + this.heap.pop(); // restore the heapify property // eslint-disable-next-line no-underscore-dangle this.__heapify(0); - return max; } - - if (this.heap.length === 1) { - this.heap.splice(this.heap.length - 1, 1); - return max; - } - return max; } diff --git a/src/_DataStructures_/Heaps/MinHeap/MinHeap.test.js b/src/_DataStructures_/Heaps/MinHeap/MinHeap.test.js new file mode 100644 index 00000000..7c47bc6c --- /dev/null +++ b/src/_DataStructures_/Heaps/MinHeap/MinHeap.test.js @@ -0,0 +1,59 @@ +const MinHeap = require('.'); + +describe('MinHeap', () => { + it('Should be a class', () => { + expect(typeof MinHeap.prototype.constructor).toEqual('function'); + }); + + const mh = new MinHeap(); + + beforeEach(() => { + mh.destroy(); + }); + + it('Should create an instance of MinHeap', () => { + expect(mh instanceof MinHeap).toEqual(true); + }); + + it('Should create a MinHeap using collection', () => { + const mHBulk = new MinHeap([112, 3, 21, 9, 10, 0]); + expect(mHBulk.getMin()).toEqual(0); + }); + + it('Should add an element to the MinHeap', () => { + mh.add(10); + expect(mh.getMin()).toEqual(10); + }); + + it('Should keep the smallest element at the root', () => { + [12, 5, 34].forEach(el => mh.add(el)); + expect(mh.getMin()).toEqual(5); + }); + + it('Should retain Heap properties after removal of an element', () => { + [12, 45, 1, 34].forEach(el => mh.add(el)); + expect(mh.getMin()).toEqual(1); + mh.remove(); + expect(mh.getMin()).toEqual(12); + }); + + it('Should return `null` when heap is empty', () => { + [1, 34].forEach(el => mh.add(el)); + expect(mh.getMin()).toEqual(1); + mh.remove(); + mh.remove(); + expect(mh.getMin()).toEqual(null); + }); + + it('Should return the elelment value on `remove()`', () => { + [1, 34].forEach(el => mh.add(el)); + expect(mh.getMin()).toEqual(1); + expect(mh.remove()).toEqual(1); + expect(mh.remove()).toEqual(34); + expect(mh.getMin()).toEqual(null); + }); + + it('Should return `null` on `remove() called on empty heap`', () => { + expect(mh.getMin()).toEqual(null); + }); +}); diff --git a/src/_DataStructures_/Heaps/MinHeap/index.js b/src/_DataStructures_/Heaps/MinHeap/index.js new file mode 100644 index 00000000..d5a3e370 --- /dev/null +++ b/src/_DataStructures_/Heaps/MinHeap/index.js @@ -0,0 +1,78 @@ +class MinHeap { + constructor(collection) { + this.heap = []; + + if (collection) { + collection.forEach((element) => { + this.add(element); + }); + } + } + + add(element) { + this.heap.push(element); + // check for the parent element & swap if required + // eslint-disable-next-line no-underscore-dangle + this.__traverseUpAndSwap(this.heap.length - 1); + } + + getMin() { + return this.heap[0] !== undefined ? this.heap[0] : null; + } + + remove() { + const min = this.heap[0] !== undefined ? this.heap[0] : null; + if (this.heap.length === 1) { + this.heap.pop(); + } + if (this.heap.length> 1) { + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap.pop(); + // eslint-disable-next-line no-underscore-dangle + this.__heapify(0); + } + return min; + } + + destroy() { + this.heap = []; + } + + // eslint-disable-next-line consistent-return + __traverseUpAndSwap(index) { + if (index <= 0) return null; + + const parent = Math.floor(index / 2); + + if (this.heap[parent]> this.heap[index]) { + const temp = this.heap[parent]; + this.heap[parent] = this.heap[index]; + this.heap[index] = temp; + // eslint-disable-next-line no-underscore-dangle + this.__traverseUpAndSwap(parent); + } + } + + __heapify(index) { + const left = index * 2; + const right = index * 2 + 1; + + let smallest = index; + + if (this.heap.length> left && this.heap[smallest]> this.heap[left]) { + smallest = left; + } + if (this.heap.length> right && this.heap[smallest]> this.heap[right]) { + smallest = right; + } + if (smallest !== index) { + const tmp = this.heap[smallest]; + this.heap[smallest] = this.heap[index]; + this.heap[index] = tmp; + // eslint-disable-next-line no-underscore-dangle + this.__heapify(smallest); + } + } +} + +module.exports = MinHeap; diff --git a/src/_DataStructures_/Heaps/k-largest-in-array/index.js b/src/_DataStructures_/Heaps/k-largest-in-array/index.js new file mode 100644 index 00000000..e1d16e90 --- /dev/null +++ b/src/_DataStructures_/Heaps/k-largest-in-array/index.js @@ -0,0 +1,22 @@ +const MaxHeap = require('../MaxHeap'); + +/** + * Find the 4 largest elements from an array + */ + +function findKLargest(collection, k) { + if (!collection || !Array.isArray(collection)) { + throw new Error('Invalid / missing collection'); + } + + // create a MaxHeap using the collection + const mh = new MaxHeap(collection); + const result = []; + + for (let i = 0; i < k; i += 1) { + result.push(mh.remove()); + } + return result; +} + +module.exports = findKLargest; diff --git a/src/_DataStructures_/Heaps/k-smallest-in-array/index.js b/src/_DataStructures_/Heaps/k-smallest-in-array/index.js new file mode 100644 index 00000000..4030e0c0 --- /dev/null +++ b/src/_DataStructures_/Heaps/k-smallest-in-array/index.js @@ -0,0 +1,21 @@ +/** + * Find 4 smallest elements in an array + */ + +const MinHeap = require('../MinHeap'); + +function findKSmallest(collection, k) { + if (!collection || !Array.isArray(collection)) { + throw new Error('Invalid / missing collection'); + } + + // create a MinHeap using the collection + const mh = new MinHeap(collection); + const result = []; + for (let i = 0; i < k; i += 1) { + result.push(mh.remove()); + } + return result; +} + +module.exports = findKSmallest;

AltStyle によって変換されたページ (->オリジナル) /