diff --git a/algorithms/CPlusPlus/README.md b/algorithms/CPlusPlus/README.md index 6a713e39..13139d2d 100644 --- a/algorithms/CPlusPlus/README.md +++ b/algorithms/CPlusPlus/README.md @@ -33,6 +33,7 @@ - [Sparse Matrix](Arrays/sparse_matrix.cpp) + ## Dynamic-Programming - [Longest Common Subsequence](Dynamic-Programming/longest-common-subsequence.cpp) @@ -128,6 +129,7 @@ - [Boyer Moore pattern search](Strings/Boyer_Moore.cpp) - [Longest common prefix](Strings/longest-common-prefix.cpp) - [First unique character in the string](Strings/first-unique-character.cpp) +- [Sliding Window to match target string](Strings/sliding-window.cpp) ## Trees diff --git a/algorithms/CPlusPlus/Strings/sliding-window.cpp b/algorithms/CPlusPlus/Strings/sliding-window.cpp new file mode 100644 index 00000000..a5f60cd4 --- /dev/null +++ b/algorithms/CPlusPlus/Strings/sliding-window.cpp @@ -0,0 +1,42 @@ +/* +Description: A program to find target sub string in given string + +Approach: Using sliding window technique to compare every possible substring with the target string. +It also supports variable length target inputs since we are initialising window size with size of target + +Time complexity: O(n) +*/ + +#include +#include + +using namespace std; + +void sliding(string s,string target){ + int window_size=target.size(); + bool notfound=true; + for(int i=0;i>target; + + sliding(s,target); + + return 0; +} \ No newline at end of file diff --git a/algorithms/Java/Maths/roman-numerals.java b/algorithms/Java/Maths/roman-numerals.java index 55dda0fc..3f907f41 100644 --- a/algorithms/Java/Maths/roman-numerals.java +++ b/algorithms/Java/Maths/roman-numerals.java @@ -10,7 +10,7 @@ import java.util.HashMap; * ---------------------------------------------------------------------------------------------------------------- * * Constraints: - * The input sting should contain only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M'). + * The input string should contain only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M'). * It is guaranteed that the input is a valid roman numeral in the range [1, 3999]. * * ---------------------------------------------------------------------------------------------------------------- diff --git a/algorithms/JavaScript/README.md b/algorithms/JavaScript/README.md index 705c22d0..11c9b934 100644 --- a/algorithms/JavaScript/README.md +++ b/algorithms/JavaScript/README.md @@ -47,4 +47,5 @@ ## Heaps -- [Max Heap](src/heaps/max-heap.js) \ No newline at end of file +- [Max Heap](src/heaps/max-heap.js) +- [Min Heap](src/heaps/min-heap.js) diff --git a/algorithms/JavaScript/src/heaps/min-heap.js b/algorithms/JavaScript/src/heaps/min-heap.js new file mode 100644 index 00000000..a78b190f --- /dev/null +++ b/algorithms/JavaScript/src/heaps/min-heap.js @@ -0,0 +1,155 @@ + +// A binary heap is a partially ordered binary tree +// that satisfies the heap property. +// The heap property specifies a relationship between parent and child nodes. +// In a min heap, all child nodes are larger than +// or equal to their parent nodes. +// Heaps are represented using arrays because +// it is faster to determine elements position and it needs +// less memory space as we don't need to maintain references to child nodes. +// An example: +// consider this min heap: [null, 0, 3, 1, 10, 35, 25, 47, 15]. +// The root node is the first element 0. its children are 3 and 1. +// The general indexes formula for an element of index i are: +// the parent is at: Math.floor(i / 2) +// the left child is at: i * 2 +// the right child is at: i * 2 + 1 + +const isDefined = (value) => value !== undefined && value !== null; + +class MinHeap { + constructor() { + this.heap = [null]; + } + + // Insert a new element method + // this is a recursive method, the algorithm is: + // 1. Add the new element to the end of the array. + // 2. If the element is less large than its parent, switch them. + // 3. Continue switching until the new element is either + // larger than its parent or you reach the root of the tree. + + insert(value) { + // add the new element to the end of the array + this.heap.push(value); + const place = (index) => { + const parentIndex = Math.floor(index / 2); + if (parentIndex <= 0) return; + if (this.heap[index] < this.heap[parentIndex]) { + // the switch is made here + [this.heap[parentIndex], this.heap[index]] = [ + this.heap[index], + this.heap[parentIndex], + ]; + place(parentIndex); + } + }; + // we begin the tests from the new element we added + place(this.heap.length - 1); + }; + + // Print heap content method + print() { + return this.heap; + }; + + // Remove an element from the heap + // it's also a recursive method, the algorithm will reestablish + // the heap property after removing the root: + // 1. Move the last element in the heap into the root position. + // 2. If either child of the root is less large than it, + // swap the root with the child of the least large value. + // 3. Continue swapping until the parent is less great than both + // children or you reach the last level in the tree. + + remove() { + // save the root value element because this method will return it + const removed = this.heap[1]; + // the last element of the array is moved to the root position + this.heap[1] = this.heap[this.heap.length - 1]; + // the last element is removed from the array + this.heap.splice(this.heap.length - 1, 1); + + const place = (index) => { + if (index === this.heap.length - 1) return; + const child1Index = 2 * index; + const child2Index = child1Index + 1; + const child1 = this.heap[child1Index]; + const child2 = this.heap[child2Index]; + let newIndex = index; + // if the parent is greater than its two children + // then the heap property is respected + if ( + (!isDefined(child1) || this.heap[newIndex] <= child1) && + (!isDefined(child2) || this.heap[newIndex] <= child2) + ) { + return; + } + // test if the parent is larger than its left child + if (isDefined(child1) && this.heap[newIndex] > child1) { + newIndex = child1Index; + } + // test if the parent is larger than its right child + if (isDefined(child2) && this.heap[newIndex] > child2) { + newIndex = child2Index; + } + // the parent is switched with the child of the least value + if (index !== newIndex) { + [this.heap[index], this.heap[newIndex]] = [ + this.heap[newIndex], + this.heap[index], + ]; + place(newIndex); + } + }; + // start tests from the beginning of the array + place(1); + return removed; + }; + + // Sort an array using a min heap + // the elements of the array to sort were previously added one by one + // to the heap using the insert method + // the sorted array is the result of removing the heap's elements one by one + // using the remove method until it is empty + sort() { + const arr = []; + while (this.heap.length > 1) { + arr.push(this.remove()); + } + return arr; + }; + // Verify the heap property of a given max heap + verifyHeap() { + const explore = (index) => { + if (index === this.heap.length - 1) return true; + const child1Index = 2 * index; + const child2Index = 2 * index + 1; + const child1 = this.heap[child1Index]; + const child2 = this.heap[child2Index]; + return ( + (!isDefined(child1) || + (this.heap[index] <= child1 && explore(child1Index))) && + (!isDefined(child2) || + (this.heap[index] <= child2 && explore(child2Index))) + ); + }; + return explore(1); + }; +} + +const test = new MinHeap(); +test.insert(1); +test.insert(3); +test.insert(0); +test.insert(10); +test.insert(35); +test.insert(25); +test.insert(47); +test.insert(15); +// display heap elements +console.log(test.print()); +// verify heap property +console.log(test.verifyHeap()); +// display the sorted array +console.log(test.sort());