From da941d8cdf1cfad3e2d7d46c69bd24ff7a926618 Mon Sep 17 00:00:00 2001 From: fergalhennessy Date: Thu, 11 Jan 2024 14:24:16 -0600 Subject: [PATCH] changed notes --- docs/_notes/Public/Merge K Lists.md | 2 +- ...bstring With Concatenation Of All Words.md | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 docs/_notes/Public/Substring With Concatenation Of All Words.md diff --git a/docs/_notes/Public/Merge K Lists.md b/docs/_notes/Public/Merge K Lists.md index 8653b9e9..4536e5fa 100644 --- a/docs/_notes/Public/Merge K Lists.md +++ b/docs/_notes/Public/Merge K Lists.md @@ -24,7 +24,7 @@ You are given an array of k linked-lists `lists`, where each linked list is sort ``` #### Examples: -lists = $[[1, 4, 5], [1, 3, 4], [2, 6]]$ --> $[1, 1, 2, 3, 4, 4, 5, 6]$ +lists = `[[1, 4, 5], [1, 3, 4], [2, 6]]` --> $[1, 1, 2, 3, 4, 4, 5, 6]$ lists = $[]$ --> $[]$ lists = $[[]]$ diff --git a/docs/_notes/Public/Substring With Concatenation Of All Words.md b/docs/_notes/Public/Substring With Concatenation Of All Words.md new file mode 100644 index 00000000..2992cb71 --- /dev/null +++ b/docs/_notes/Public/Substring With Concatenation Of All Words.md @@ -0,0 +1,71 @@ +--- +title: Substring With Concatenation Of All Words +feed: show +date: 2024/01/11 +tags: hard hashmap sliding-window +leetcode: 30 +--- + +## Substring With Concatenation Of All Words + +You are given a string `s`, and an array of strings `words`. All the strings of words are **of the same length** + +A **concatenated substring** in `s` is a substring that contains all the strings of any permutation of `words` concatenated. Essentially, if all the words in `words` appear exactly once consecutively, then the substring is a concatenated substring. + +*Return the starting indices of the concatenated substrings in* `s`. You can return the answer in **any order.** + +## Examples + +**Input: ** `s = "barfoothefoobarman", words = ["foo, bar"]` --> `[0, 9]` +**Input: ** `s = "wordgoodgoodgoodbestword", words = ["word", "good", "best", "word"]` --> `[]` + +### Solution 1: Brute Force Hashmap Comparison + +Let the size of `s` be `n`, let the number of elements in `words` be `m`, let the length of a word in `words` be `w`. It follows that every concatenated substring will have length `m * w`. We can brute force a solution as follows: +1. load all `words` into a hashmap `total` +2. For each length `m * w` substring of `s`, split into length `w` pieces, add the pieces to a new hashmap `prospect` and check `prospect == total` +3. Return a vector of all the indices where step 2 is true. +Putting these steps into code, we get this solution: + +``` +class Solution{ +public: + vector findSubstring(string s, vector& words){ + vector res; + if(words.size() == 0) return res; + unordered_map total; + for(string& word: words){ + total[word]++; + } + int m = words.size(); + int w = words[0].size(); + for(int i = 0; i < s.size() - (m*w) + 1; ++i){ + unordered_map prospect; + int j = i; + while(j < i + (m*w)){ + string word = s.substr(j, w); + prospect[word] += 1; + j+= w; + } + if(prospect == total) res.push_back(i); + } + return res; + } +}; +``` + +##### Runtime Analysis: +1. Building `total`: `O(1) * m = O(m)` +2. Building `prospect` and comparing with `total`: `O(m*w)` (There are `(m*w)` characters in both maps) +3. Iterating through `s`: `O(n)` +Total Runtime: `O(m) + O(n * m * w) = O(n * m* w)` + +##### Space Analysis: +1. `total`: `O(m*w)` +2. `prospect`: `O(m*w)` (`n` times) +Space complexity is also `O(m*n*w)` + +Both space and time are cubic: can we do better? Looking at this solution, we do a lot of duplicate comparisons. if we create a map `prospect` and check all the internals against `total`, then discard it, we waste a lot of comparisons that we could have saved for future iterations... + +### Solution 2: Sliding Window Hashmap Comparison +