WebDevStudy

Hashmap

Ransom Note (Easy)Isosmorphic Strings (Easy)Word Pattern (Easy)Valid Anagram (Easy)Two Sum (Easy)Happy Number (Easy)Contains Duplicate II (Easy)Group Anagrams (Medium)Longest Consecutive Sequence (Medium)

Ransom Note (Easy)

Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.

Each letter in magazine can only be used once in ransomNote.

# Time complexity: O(n) # Space complexity: O(n) def canConstruct(ransomNote: str, magazine: str) -> bool: m = {} for c in magazine: m[c] = m.get(c, 0) + 1 for c in ransomNote: if c not in m or m[c] == 0: return False m[c] -= 1 return True

Isomorphic Strings (Easy)

Given two strings s and t, determine if they are isomorphic.

Two strings s and t are isomorphic if the characters in s can be replaced to get t.

All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character, but a character may map to itself. Assume s.length == t.length.

# Time complexity: O(n) # Space complexity: O(n) def isIsomorphic(self, s: str, t: str) -> bool: s2t, t2s = {}, {} for i in range(len(s)): # Characters must have the same mapping in both directions if s[i] in s2t and s2t[s[i]] != t[i]: return False if t[i] in t2s and t2s[t[i]] != s[i]: return False s2t[s[i]] = t[i] t2s[t[i]] = s[i] return True

NOTE: The solution for "Word Pattern" can also be used to solve this problem.

Word Pattern (Easy)

Given a pattern and a string s, find if s follows the same pattern.

Here 'follow' means a full match, such that there is a bijection between a letter in pattern and a non-empty word in s.

Example: Input pattern = "abba", s = "dog cat cat dog" Output true

# Time complexity: O(n) # Space complexity: O(n) # Example: "abba" -> (0, 1, 1, 0) def convertPatternToTuple(string: str) -> tuple: m = {} count = 0 result = [] for c in string: if c in m: result.append(m[c]) else: m[c] = count result.append(count) count += 1 return tuple(result) # Example: "dog cat cat dog" -> (0, 1, 1, 0) def convertWordsToTuple(words: str) -> tuple: m = {} count = 0 result = [] words = words.split() for word in words: if word in m: result.append(m[word]) else: m[word] = count result.append(count) count += 1 return tuple(result) def wordPattern(pattern: str, s: str) -> bool: return convertPatternToTuple(pattern) == convertWordsToTuple(s)

Valid Anagram (Easy)

Given two strings s and t, return true if t is an anagram of s, and false otherwise.

An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

# Time complexity: O(n) # Space complexity: O(n) def isAnagram(s: str, t: str) -> bool: if len(s) != len(t): return False m = {} for c in s: m[c] = m.get(c, 0) + 1 for c in t: if c not in m or m[c] == 0: return False m[c] -= 1 return True

Two Sum (Easy)

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

# Time complexity: O(n) # Space complexity: O(n) def twoSum(nums: List[int], target: int) -> List[int]: m = {} for i in range(len(nums)): comp = target - nums[i] if comp in m: return [i, m[comp]] m[nums[i]] = i

Happy Number (Easy)

Write an algorithm to determine if a number n is happy.

A happy number is a number defined by the following process:

  • Starting with any positive integer, replace the number by the sum of the squares of its digits.
  • Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.
  • Those numbers for which this process ends in 1 are happy.

Return true if n is a happy number, and false if not.

# Time complexity: O(n) # Space complexity: O(n) def isHappy(n: int) -> bool: m = set() while True: if n in m: return False else: m.add(n) li = list(str(n)) sum = 0 for c in li: sum += int(c) ** 2 if sum == 1: return True n = sum

Contains Duplicate II (Easy)

Given an integer array nums and an integer k, return true if there are two distinct indices i and j in the array such that nums[i] == nums[j] and abs(i - j) <= k.

# Time complexity: O(n) # Space complexity: O(n) def containsNearbyDuplicate(nums: List[int], k: int) -> bool: m = {} for i in range(len(nums)): if nums[i] not in m: m[nums[i]] = i else: if abs(i - m[nums[i]]) <= k: return True m[nums[i]] = i return False

Group Anagrams (Medium)

Given an array of strings strs, group the anagrams together. You can return the answer in any order.

An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

# Time complexity: O(n * m * log(m)) # Space complexity: O(n * m) def groupAnagrams(strs: List[str]) -> List[List[str]]: answer = {} for word in strs: w = "".join(sorted(word)) if w in answer: answer[w].append(word) else: answer[w] = [word] return list(answer.values())

Alternative solution:

# Time complexity: O(n * m) # Space complexity: O(n * m) def groupAnagrams(strs: List[str]) -> List[List[str]]: m = {} for word in strs: # Use list to count char frequency chars = [0] * 26 for char in word: chars[ord(char) - 97] += 1 # Use frequency as map key tup = tuple(chars) if tup in m: m[tup].append(word) else: m[tup] = [word] return [m[tup] for tup in m]

Longest Consecutive Sequence (Medium)

Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence.

Write an algorithm that runs in O(n) time.

# Time complexity: O(n) # Space complexity: O(n) def longestConsecutive(nums: List[int]) -> int: s = set(nums) answer = 0 for n in nums: # n is lowest value aka start of own sequence if n - 1 not in s: end = n + 1 while end in s: end += 1 answer = max(answer, end - n) return answer