diff --git a/14. Group Anagrams.py b/14. Group Anagrams.py new file mode 100644 index 00000000..d1958c8b --- /dev/null +++ b/14. Group Anagrams.py @@ -0,0 +1,25 @@ +#Group Anagrams + +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + # Using prime number hashing to identify anagrams + def getPrimes(str): + # Computing hash by multiplying prime numbers assigned to each character + hash = 1 + primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101] + for s in str: + # Multiplying hash with prime corresponding to each character + hash *= primes[ord(s) - ord('a')] + return hash + + # Storing strings grouped by their hash values + result = defaultdict(list) + for s in strs: + # Computing hash for each string and grouping anagrams together + hashValue = getPrimes(s) + result[hashValue].append(s) + # Returning all grouped anagrams + return list(result.values()) + +# TC: O(n * k) where n is number of strings and k is average length of string +# SC: O(n * k) for storing all strings in the result dictionary \ No newline at end of file diff --git a/15. Isomorphic Strings.py b/15. Isomorphic Strings.py new file mode 100644 index 00000000..c80062b9 --- /dev/null +++ b/15. Isomorphic Strings.py @@ -0,0 +1,37 @@ +15. Isomorphic Strings + + +class Solution: + def isIsomorphic(self, s: str, t: str) -> bool: + # We are maintaining two mappings to ensure one-to-one character correspondence + smap = {} # Mapping characters from s to t + tmap = {} # Mapping characters from t to s + + # We are iterating through each character pair in both strings + for i in range(len(s)): + sChar = s[i] + tChar = t[i] + + # We are checking if sChar already has a mapping + if sChar in smap: + # We are verifying the mapping is consistent + if smap[sChar] != tChar: + return False + else: + # We are creating a new mapping from s to t + smap[sChar] = tChar + + # We are checking if tChar already has a mapping + if tChar in tmap: + # We are verifying the reverse mapping is consistent + if tmap[tChar] != sChar: + return False + else: + # We are creating a new reverse mapping from t to s + tmap[tChar] = sChar + + # We are returning True if all character mappings are consistent + return True + +# Time Complexity (TC): O(n) - where n is the length of string s +# Space Complexity (SC): O(1) - at most 26 lowercase letters in each map (constant space) \ No newline at end of file diff --git a/16. Word Pattern.py b/16. Word Pattern.py new file mode 100644 index 00000000..d9c6cd9e --- /dev/null +++ b/16. Word Pattern.py @@ -0,0 +1,29 @@ +class Solution: + def wordPattern(self, pattern: str, s: str) -> bool: + # Splitting the string into words + words = s.split(" ") + # Checking if the number of words matches the pattern length + if len(words) != len(pattern): + return False + # Creating a mapping from pattern characters to words + pat_to_words = {} + # Creating a reverse mapping from words to pattern characters + words_to_pat = {} + + # Iterating through each pattern character and corresponding word + for p, w in zip(pattern, words): + # Checking if pattern character already exists with a different word + if p in pat_to_words and pat_to_words[p] != w: + return False + # Checking if word already exists with a different pattern character + if w in words_to_pat and words_to_pat[w] != p: + return False + # Mapping pattern character to word + pat_to_words[p] = w + # Mapping word to pattern character + words_to_pat[w] = p + # Returning True if all mappings are consistent + return True + +# Time Complexity (TC): O(n) where n is the length of pattern/words +# Space Complexity (SC): O(k) where k is the number of unique characters in pattern