From 242670022769879936cf14c88e4f37b422e76b7d Mon Sep 17 00:00:00 2001 From: Aditya1942 Date: Mon, 1 Nov 2021 16:34:08 +0530 Subject: [PATCH 1/4] new algorithm 'Sliding-Window' added with example 'Longest Substring Without Repeating Characters' --- ...gestSubstringWithoutRepeatingCharacters.js | 49 +++++++++++++++++++ ...ubstringWithoutRepeatingCharacters.test.js | 11 +++++ 2 files changed, 60 insertions(+) create mode 100644 Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js create mode 100644 Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js diff --git a/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js b/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js new file mode 100644 index 0000000000..ae497c78e5 --- /dev/null +++ b/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js @@ -0,0 +1,49 @@ +/** + * @name The-Sliding-Window Algorithm is primarily used for the problems dealing with linear data structures like Arrays, Lists, Strings etc. + * These problems can easily be solved using Brute Force techniques which result in quadratic or exponential time complexity. + * Sliding window technique reduces the required time to linear O(n). + * @see [The-Sliding-Window](https://www.geeksforgeeks.org/window-sliding-technique/) + */ + +/** + * @function Get Longest Substring Without Repeating Characters + * @description Get the length of the longest substring without repeating characters + * @param {String} str - The input string + */ +export function LongestSubstringWithoutRepeatingCharacters (s) { + let maxLength = 0 + let start = 0 + let end = 0 + const map = {} + while (end < s.length) { + if (map[s[end]] === undefined) { + map[s[end]] = 1 + maxLength = Math.max(maxLength, end - start + 1) + end++ + } else { + while (s[start] !== s[end]) { + delete map[s[start]] + start++ + } + delete map[s[start]] + start++ + } + } + return maxLength +} + +// Example 1: +// Input: s = "abcabcbb" +// Output: 3 +// Explanation: The answer is "abc", with the length of 3. + +// Example 2: +// Input: s = "bbbbb" +// Output: 1 +// Explanation: The answer is "b", with the length of 1. + +// Example 3: +// Input: s = "pwwkew" +// Output: 3 +// Explanation: The answer is "wke", with the length of 3. +// Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. diff --git a/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js b/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js new file mode 100644 index 0000000000..3a77a92082 --- /dev/null +++ b/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js @@ -0,0 +1,11 @@ +import { LongestSubstringWithoutRepeatingCharacters } from '../LongestSubstringWithoutRepeatingCharacters.js' + +describe('LongestSubstringWithoutRepeatingCharacters', () => { + it('should return longest substring without repeating characters', () => { + expect(LongestSubstringWithoutRepeatingCharacters('abcabcbb')).toEqual(3) + expect(LongestSubstringWithoutRepeatingCharacters('bbbbb')).toEqual(1) + expect(LongestSubstringWithoutRepeatingCharacters('pwwkew')).toEqual(3) + expect(LongestSubstringWithoutRepeatingCharacters('a')).toEqual(1) + expect(LongestSubstringWithoutRepeatingCharacters('')).toEqual(0) + }) +}) From b6d7962e31e2d1cc7313d6e3585858d0b236d682 Mon Sep 17 00:00:00 2001 From: Aditya1942 Date: Mon, 1 Nov 2021 22:16:28 +0530 Subject: [PATCH 2/4] new example of sliding window 'Permutation in String' added --- ...gestSubstringWithoutRepeatingCharacters.js | 4 +- Sliding-Window/PermutationinString.js | 59 +++++++++++++++++++ .../test/PermutationinString.test.js | 10 ++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 Sliding-Window/PermutationinString.js create mode 100644 Sliding-Window/test/PermutationinString.test.js diff --git a/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js b/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js index ae497c78e5..9b3822eeca 100644 --- a/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js +++ b/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js @@ -6,9 +6,9 @@ */ /** - * @function Get Longest Substring Without Repeating Characters + * @function LongestSubstringWithoutRepeatingCharacters * @description Get the length of the longest substring without repeating characters - * @param {String} str - The input string + * @param {String} s - The input string */ export function LongestSubstringWithoutRepeatingCharacters (s) { let maxLength = 0 diff --git a/Sliding-Window/PermutationinString.js b/Sliding-Window/PermutationinString.js new file mode 100644 index 0000000000..ddbb766aff --- /dev/null +++ b/Sliding-Window/PermutationinString.js @@ -0,0 +1,59 @@ +/** + * @name The-Sliding-Window Algorithm is primarily used for the problems dealing with linear data structures like Arrays, Lists, Strings etc. + * These problems can easily be solved using Brute Force techniques which result in quadratic or exponential time complexity. + * Sliding window technique reduces the required time to linear O(n). + * @see [The-Sliding-Window](https://www.geeksforgeeks.org/window-sliding-technique/) + */ +/** + * @function PermutationinString + * @description Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise. + * @param {String} s1 - The input string + * @param {String} s2 - The input string + * @return {boolean} - Returns true if s2 contains a permutation of s1, or false otherwise. + */ + +export function PermutationinString (s1, s2) { + if (s1.length > s2.length) return false + let start = 0 + let end = s1.length - 1 + const s1Set = SetHash() + const s2Set = SetHash() + for (let i = 0; i < s1.length; i++) { + s1Set[s1[i]]++ + s2Set[s2[i]]++ + } + if (equals(s1Set, s2Set)) return true + while (end < s2.length - 1) { + if (equals(s1Set, s2Set)) return true + end++ + console.log(s2[start], s2[end], equals(s1Set, s2Set)) + const c1 = s2[start] + const c2 = s2[end] + if (s2Set[c1] > 0) s2Set[c1]-- + s2Set[c2]++ + start++ + if (equals(s1Set, s2Set)) return true + } + return false +} +function equals (a, b) { + return JSON.stringify(a) === JSON.stringify(b) +} + +function SetHash () { + const set = new Set() + const alphabets = 'abcdefghijklmnopqrstuvwxyz' + for (let i = 0; i < alphabets.length; i++) { + set[alphabets[i]] = 0 + } + return set +} + +// Example 1: +// Input: s1 = "ab", s2 = "eidbaooo" +// Output: true +// Explanation: s2 contains one permutation of s1 ("ba"). + +// Example 2: +// Input: s1 = "ab", s2 = "eidboaoo" +// Output: false diff --git a/Sliding-Window/test/PermutationinString.test.js b/Sliding-Window/test/PermutationinString.test.js new file mode 100644 index 0000000000..8ffe9accc9 --- /dev/null +++ b/Sliding-Window/test/PermutationinString.test.js @@ -0,0 +1,10 @@ +import { PermutationinString } from '../PermutationinString.js' + +describe('PermutationinString', () => { + it("should return true if one of s1's permutations is the substring of s2", () => { + expect(PermutationinString('ab', 'eidbaooo')).toEqual(true) + expect(PermutationinString('abc', 'bcab')).toEqual(true) + expect(PermutationinString('ab', 'eidboaoo')).toEqual(false) + expect(PermutationinString('abc', '')).toEqual(false) + }) +}) From 7bf3536fc46dc4448a367729c31c71b7e7e1670e Mon Sep 17 00:00:00 2001 From: Rak Laptudirm Date: Tue, 2 Nov 2021 10:41:59 +0530 Subject: [PATCH 3/4] chore: add `ignore_words_list` --- .github/workflows/Codespell.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Codespell.yml b/.github/workflows/Codespell.yml index 0c421e95bc..4871671154 100644 --- a/.github/workflows/Codespell.yml +++ b/.github/workflows/Codespell.yml @@ -10,4 +10,4 @@ jobs: with: # file types to ignore skip: "*.json,*.yml,DIRECTORY.md,PermutateString.test.js,SubsequenceRecursive.js" - + ignore_words_list: "ba" From ba42b936e4ea084ed78f605f4e5c41dc74d62428 Mon Sep 17 00:00:00 2001 From: Aditya1942 Date: Tue, 2 Nov 2021 10:52:24 +0530 Subject: [PATCH 4/4] sliding-window moved into Dynamic-programming directory --- .../Sliding-Window}/LongestSubstringWithoutRepeatingCharacters.js | 0 .../Sliding-Window}/PermutationinString.js | 0 .../test/LongestSubstringWithoutRepeatingCharacters.test.js | 0 .../Sliding-Window}/test/PermutationinString.test.js | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {Sliding-Window => Dynamic-Programming/Sliding-Window}/LongestSubstringWithoutRepeatingCharacters.js (100%) rename {Sliding-Window => Dynamic-Programming/Sliding-Window}/PermutationinString.js (100%) rename {Sliding-Window => Dynamic-Programming/Sliding-Window}/test/LongestSubstringWithoutRepeatingCharacters.test.js (100%) rename {Sliding-Window => Dynamic-Programming/Sliding-Window}/test/PermutationinString.test.js (100%) diff --git a/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js b/Dynamic-Programming/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js similarity index 100% rename from Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js rename to Dynamic-Programming/Sliding-Window/LongestSubstringWithoutRepeatingCharacters.js diff --git a/Sliding-Window/PermutationinString.js b/Dynamic-Programming/Sliding-Window/PermutationinString.js similarity index 100% rename from Sliding-Window/PermutationinString.js rename to Dynamic-Programming/Sliding-Window/PermutationinString.js diff --git a/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js b/Dynamic-Programming/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js similarity index 100% rename from Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js rename to Dynamic-Programming/Sliding-Window/test/LongestSubstringWithoutRepeatingCharacters.test.js diff --git a/Sliding-Window/test/PermutationinString.test.js b/Dynamic-Programming/Sliding-Window/test/PermutationinString.test.js similarity index 100% rename from Sliding-Window/test/PermutationinString.test.js rename to Dynamic-Programming/Sliding-Window/test/PermutationinString.test.js