classHashTable(object):""" HashMap Data Type HashMap() Create a new, empty map. It returns an empty map collection. put(key, val) Add a new key-value pair to the map. If the key is already in the map then replace the old value with the new value. get(key) Given a key, return the value stored in the map or None otherwise. del_(key) or del map[key] Delete the key-value pair from the map using a statement of the form del map[key]. len() Return the number of key-value pairs stored in the map. in Return True for a statement of the form key in map, if the given key is in the map, False otherwise. """ _empty =object() _deleted =object()def__init__(self,size=11): self.size = size self._len =0 self._keys = [self._empty] * size # keys self._values = [self._empty] * size # valuesdefput(self,key,value): initial_hash = hash_ = self.hash(key)whileTrue:if self._keys[hash_]is self._empty or self._keys[hash_]is self._deleted:# can assign to hash_ index self._keys[hash_]= key self._values[hash_]= value self._len +=1returnelif self._keys[hash_]== key:# key already exists here, assign over self._keys[hash_]= key self._values[hash_]= valuereturn hash_ = self._rehash(hash_)if initial_hash == hash_:# table is fullraiseValueError("Table is full")defget(self,key): initial_hash = hash_ = self.hash(key)whileTrue:if self._keys[hash_]is self._empty:# That key was never assignedreturnNoneelif self._keys[hash_]== key:# key foundreturn self._values[hash_] hash_ = self._rehash(hash_)if initial_hash == hash_:# table is full and wrapped aroundreturnNonedefdel_(self,key): initial_hash = hash_ = self.hash(key)whileTrue:if self._keys[hash_]is self._empty:# That key was never assignedreturnNoneelif self._keys[hash_]== key:# key found, assign with deleted sentinel self._keys[hash_]= self._deleted self._values[hash_]= self._deleted self._len -=1return hash_ = self._rehash(hash_)if initial_hash == hash_:# table is full and wrapped aroundreturnNonedefhash(self,key):return key % self.sizedef_rehash(self,old_hash):""" linear probing """return (old_hash +1) % self.sizedef__getitem__(self,key):return self.get(key)def__delitem__(self,key):return self.del_(key)def__setitem__(self,key,value): self.put(key, value)def__len__(self):return self._lenclassResizableHashTable(HashTable): MIN_SIZE =8def__init__(self):super().__init__(self.MIN_SIZE)defput(self,key,value): rv =super().put(key, value)# increase size of dict * 2 if filled >= 2/3 size (like python dict)iflen(self)>= (self.size *2) /3: self.__resize()def__resize(self): keys, values = self._keys, self._values self.size *=2# this will be the new size self._len =0 self._keys = [self._empty] * self.size self._values = [self._empty] * self.sizefor key, value inzip(keys, values):if key isnot self._empty and key isnot self._deleted: self.put(key, value)from.hashtable import*from.separate_chaining_hashtable import*from.word_pattern import*from.is_isomorphic import*from.is_anagram import*"""Given two strings s and t , write a function to determine if t is an anagram of s.Example 1:Input: s = "anagram", t = "nagaram"Output: trueExample 2:Input: s = "rat", t = "car"Output: falseNote:You may assume the string contains only lowercase alphabets.Reference: https://leetcode.com/problems/valid-anagram/description/"""defis_anagram(s,t):""" :type s: str :type t: str :rtype: bool """ maps ={} mapt ={}for i in s: maps[i]= maps.get(i, 0)+1for i in t: mapt[i]= mapt.get(i, 0)+1return maps == mapt"""Given two strings s and t, determine if they are isomorphic.Two strings are isomorphic if the characters in s can be replaced to get t.All occurrences of a character must be replaced with another character whilepreserving the order of characters. No two characters may map to the samecharacter but a character may map to itself.Example 1:Input: s = "egg", t = "add"Output: trueExample 2:Input: s = "foo", t = "bar"Output: falseExample 3:Input: s = "paper", t = "title"Output: trueReference: https://leetcode.com/problems/isomorphic-strings/description/"""defis_isomorphic(s,t):""" :type s: str :type t: str :rtype: bool """iflen(s)!=len(t):returnFalsedict={} set_value =set()for i inrange(len(s)):if s[i]notindict:if t[i]in set_value:returnFalse dict[s[i]]= t[i] set_value.add(t[i])else:if dict[s[i]]!= t[i]:returnFalsereturnTrue"""Given string a and b, with b containing all distinct characters,find the longest common sub sequence's length.Expected complexity O(n logn)."""defmax_common_sub_string(s1,s2):# Assuming s2 has all unique chars s2dic ={s2[i]: i for i inrange(len(s2))} maxr =0 subs ="" i =0while i <len(s1):if s1[i]in s2dic: j = s2dic[s1[i]] k = iwhile j <len(s2)and k <len(s1)and s1[k]== s2[j]: k +=1 j +=1if k - i > maxr: maxr = k - i subs = s1[i:k] i = kelse: i +=1return subsdeflongest_palindromic_subsequence(str): n =len(str)# Create a table to store results of subproblems L = [[0for x inrange(n)] for x inrange(n)]for i inrange(n): L[i][i] =1for sub_string_length inrange(2, n +1):for i inrange(n - sub_string_length +1): j = i + sub_string_length -1if str[i]== str[j]and sub_string_length ==2: L[i][j] =2elif str[i]== str[j]: L[i][j] = L[i +1][j -1] +2else: L[i][j] =max(L[i][j -1], L[i +1][j])return L[0][n -1]"""Design a data structure that supports all following operationsin average O(1) time.insert(val): Inserts an item val to the set if not already present.remove(val): Removes an item val from the set if present.getRandom: Returns a random element from current set of elements.Each element must have the same probability of being returned."""import randomclassRandomizedSet:def__init__(self): self.nums = [] self.idxs ={}definsert(self,val):if val notin self.idxs: self.nums.append(val) self.idxs[val]=len(self.nums)-1returnTruereturnFalsedefremove(self,val):if val in self.idxs: idx, last = self.idxs[val], self.nums[-1] self.nums[idx], self.idxs[last]= last, idx self.nums.pop() self.idxs.pop(val, 0)returnTruereturnFalsedefget_random(self): idx = random.randint(0, len(self.nums) -1)return self.nums[idx]if__name__=="__main__": rs =RandomizedSet()print("insert 1: ", rs.insert(1))print("insert 2: ", rs.insert(2))print("insert 3: ", rs.insert(3))print("insert 4: ", rs.insert(4))print("remove 3: ", rs.remove(3))print("remove 3: ", rs.remove(3))print("remove 1: ", rs.remove(1))print("random: ", rs.get_random())print("random: ", rs.get_random())print("random: ", rs.get_random())print("random: ", rs.get_random())import unittestclassNode(object):def__init__(self,key=None,value=None,next=None): self.key = key self.value = value self.next =nextclassSeparateChainingHashTable(object):""" HashTable Data Type: By having each bucket contain a linked list of elements that are hashed to that bucket. Usage:>>> table = SeparateChainingHashTable() # Create a new, empty map.>>> table.put('hello', 'world') # Add a new key-value pair.>>> len(table) # Return the number of key-value pairs stored in the map. 1>>> table.get('hello') # Get value by key. 'world'>>> del table['hello'] # Equivalent to `table.del_('hello')`, deleting key-value pair.>>> table.get('hello') is None # Return `None` if a key doesn't exist. True """ _empty =Nonedef__init__(self,size=11): self.size = size self._len =0 self._table = [self._empty] * sizedefput(self,key,value): hash_ = self.hash(key) node_ = self._table[hash_]if node_ is self._empty: self._table[hash_]=Node(key, value)else:while node_.next isnotNone:if node_.key == key: node_.value = valuereturn node_ = node_.next node_.next =Node(key, value) self._len +=1defget(self,key): hash_ = self.hash(key) node_ = self._table[hash_]while node_ isnot self._empty:if node_.key == key:return node_.value node_ = node_.nextreturnNonedefdel_(self,key): hash_ = self.hash(key) node_ = self._table[hash_] pre_node =Nonewhile node_ isnotNone:if node_.key == key:if pre_node isNone: self._table[hash_]= node_.nextelse: pre_node.next = node_.next self._len -=1 pre_node = node_ node_ = node_.nextdefhash(self,key):returnhash(key)% self.sizedef__len__(self):return self._lendef__getitem__(self,key):return self.get(key)def__delitem__(self,key):return self.del_(key)def__setitem__(self,key,value): self.put(key, value)"""Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.The Sudoku board could be partially filled, where empty cells are filled withthe character '.'."""defis_valid_sudoku(self,board): seen = []for i, row inenumerate(board):for j, c inenumerate(row):if c !=".": seen += [(c, j), (i, c), (i /3, j /3, c)]returnlen(seen)==len(set(seen))"""Given a pattern and a string str, find if str follows the same pattern.Here follow means a full match, such that there is a bijection between aletter in pattern and a non-empty word in str.Example 1:Input: pattern = "abba", str = "dog cat cat dog"Output: trueExample 2:Input:pattern = "abba", str = "dog cat cat fish"Output: falseExample 3:Input: pattern = "aaaa", str = "dog cat cat dog"Output: falseExample 4:Input: pattern = "abba", str = "dog dog dog dog"Output: falseNotes:You may assume pattern contains only lowercase letters, and str contains lowercase letters separated by a single space.Reference: https://leetcode.com/problems/word-pattern/description/"""defword_pattern(pattern,str):dict={} set_value =set() list_str =str.split()iflen(list_str)!=len(pattern):returnFalsefor i inrange(len(pattern)):if pattern[i]notindict:if list_str[i]in set_value:returnFalse dict[pattern[i]]= list_str[i] set_value.add(list_str[i])else:if dict[pattern[i]]!= list_str[i]:returnFalsereturnTrue