From aadea1fa64b853d23208c447c818d23e44f6bcbb Mon Sep 17 00:00:00 2001 From: Rhyannon Date: Tue, 19 Jul 2022 21:06:41 -0600 Subject: [PATCH 1/5] passes grouped_anagrams test --- hash_practice/exercises.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/hash_practice/exercises.py b/hash_practice/exercises.py index 48bf95e..38ccbed 100644 --- a/hash_practice/exercises.py +++ b/hash_practice/exercises.py @@ -1,11 +1,21 @@ - def grouped_anagrams(strings): """ This method will return an array of arrays. Each subarray will have strings which are anagrams of each other - Time Complexity: ? - Space Complexity: ? + Time Complexity: While there appears only a single for-loop, + .join() adds O(N) & sorted() adds O(nlogn) during their ideal case + Space Complexity: We're adding a new data structure, the anagrams_hash, + meaning we're adding linear O(N) space based on the size of this new hash table + We're also adding an auxiliary sorted_anagram string """ - pass + anagrams_hash = {} + for anagram in strings: + sorted_anagram = "".join(sorted(anagram)) + if sorted_anagram in anagrams_hash: + anagrams_hash[sorted_anagram].append(anagram) + else: + anagrams_hash[sorted_anagram] = [anagram] + + return list(anagrams_hash.values()) def top_k_frequent_elements(nums, k): """ This method will return the k most common elements @@ -27,3 +37,4 @@ def valid_sudoku(table): """ pass +print(grouped_anagrams(["eat", "tea", "tan", "ate", "nat", "bat"])) \ No newline at end of file From d9393bbc24622d1bbca5a1ee53dbe7cb89ed7db5 Mon Sep 17 00:00:00 2001 From: Rhyannon Date: Tue, 19 Jul 2022 21:19:33 -0600 Subject: [PATCH 2/5] passing 2 top_k tests --- hash_practice/exercises.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/hash_practice/exercises.py b/hash_practice/exercises.py index 38ccbed..1faaad3 100644 --- a/hash_practice/exercises.py +++ b/hash_practice/exercises.py @@ -23,7 +23,28 @@ def top_k_frequent_elements(nums, k): Time Complexity: ? Space Complexity: ? """ - pass + num_frequency = {} + frequency_dict = {} + for i in nums: + if i not in num_frequency: + num_frequency[i] = 1 + else: + num_frequency[i] += 1 + + for key, value in num_frequency.items(): + if value not in frequency_dict: + frequency_dict[value] = [key] + else: + frequency_dict[value].append(key) + + top_k_freq_ele = [] + for i in range(len(nums), 0, -1): + if i in top_k_freq_ele: + top_k_freq_ele.extend(frequency_dict[i]) + if len(top_k_freq_ele) >= k: + break + + return top_k_freq_ele def valid_sudoku(table): From 040feb605fd0e341bea6f9a01752ea6539bb31c9 Mon Sep 17 00:00:00 2001 From: Rhyannon Date: Sun, 24 Jul 2022 20:15:53 -0600 Subject: [PATCH 3/5] skeleton for sudoku, not passing tests --- hash_practice/exercises.py | 74 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/hash_practice/exercises.py b/hash_practice/exercises.py index 1faaad3..73ebadf 100644 --- a/hash_practice/exercises.py +++ b/hash_practice/exercises.py @@ -46,6 +46,68 @@ def top_k_frequent_elements(nums, k): return top_k_freq_ele +def not_in_row(arr, row): + + # Set to store characters seen so far. + st = set() + + for i in range(0, 9): + + # If already encountered before, + # return false + if arr[row][i] in st: + return False + + # If it is not an empty cell, insert value + # at the current cell in the set + if arr[row][i] != '.': + st.add(arr[row][i]) + + return True + +def not_in_col(arr, col): + + st = set() + + for i in range(0, 9): + + # If already encountered before, + # return false + if arr[i][col] in st: + return False + + # If it is not an empty cell, insert + # value at the current cell in the set + if arr[i][col] != '.': + st.add(arr[i][col]) + + return True + +def not_in_box(arr, startRow, startCol): + + st = set() + + for row in range(0, 3): + for col in range(0, 3): + curr = arr[row + startRow][col + startCol] + + # If already encountered before, + # return false + if curr in st: + return False + + # If it is not an empty cell, + # insert value at current cell in set + if curr != '.': + st.add(curr) + + return True + +def isValid(arr, row, col): + + return (not_in_row(arr, row) and not_in_col(arr, col) and + not_in_box(arr, row - row % 3, col - col % 3)) + def valid_sudoku(table): """ This method will return the true if the table is still @@ -56,6 +118,12 @@ def valid_sudoku(table): Time Complexity: ? Space Complexity: ? """ - pass - -print(grouped_anagrams(["eat", "tea", "tan", "ate", "nat", "bat"])) \ No newline at end of file + for i in range(0, n): + for j in range(0, n): + + # If current row or current column or + # current 3x3 box is not valid, return false + if not isValid(table, i, j): + return False + + return True From 66d73dd73033df01fd5cf9fba298f6b53b18b339 Mon Sep 17 00:00:00 2001 From: Rhyannon Date: Sun, 24 Jul 2022 20:25:23 -0600 Subject: [PATCH 4/5] passes all sudoku tests --- hash_practice/exercises.py | 43 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/hash_practice/exercises.py b/hash_practice/exercises.py index 73ebadf..b773537 100644 --- a/hash_practice/exercises.py +++ b/hash_practice/exercises.py @@ -46,65 +46,62 @@ def top_k_frequent_elements(nums, k): return top_k_freq_ele + +# helper functions for sudoku +# using sets, not hash tables def not_in_row(arr, row): # Set to store characters seen so far. - st = set() + temp_set = set() for i in range(0, 9): # If already encountered before, # return false - if arr[row][i] in st: + if arr[row][i] in temp_set: return False # If it is not an empty cell, insert value # at the current cell in the set if arr[row][i] != '.': - st.add(arr[row][i]) + temp_set.add(arr[row][i]) return True def not_in_col(arr, col): - - st = set() - + temp_set = set() for i in range(0, 9): - # If already encountered before, # return false - if arr[i][col] in st: + if arr[i][col] in temp_set: return False # If it is not an empty cell, insert # value at the current cell in the set if arr[i][col] != '.': - st.add(arr[i][col]) + temp_set.add(arr[i][col]) return True def not_in_box(arr, startRow, startCol): - - st = set() - + temp_set = set() for row in range(0, 3): for col in range(0, 3): curr = arr[row + startRow][col + startCol] # If already encountered before, # return false - if curr in st: + if curr in temp_set: return False # If it is not an empty cell, # insert value at current cell in set if curr != '.': - st.add(curr) + temp_set.add(curr) return True -def isValid(arr, row, col): - +def is_valid(arr, row, col): return (not_in_row(arr, row) and not_in_col(arr, col) and not_in_box(arr, row - row % 3, col - col % 3)) @@ -115,15 +112,17 @@ def valid_sudoku(table): Each element can either be a ".", or a digit 1-9 The same digit cannot appear twice or more in the same row, column or 3x3 subgrid - Time Complexity: ? - Space Complexity: ? + Time Complexity: Quadratic O(N^2) - nested for loop + Space Complexity: Constant O(1) - not initializing any new data structures; + unless we're counting temp sets from our helper functions + """ - for i in range(0, n): - for j in range(0, n): - + length = len(table) + for i in range(0, length): + for j in range(0, length): # If current row or current column or # current 3x3 box is not valid, return false - if not isValid(table, i, j): + if not is_valid(table, i, j): return False return True From 8107d28598766d67d9bc332d03b6fb140c76a416 Mon Sep 17 00:00:00 2001 From: Rhyannon Date: Sun, 24 Jul 2022 20:42:13 -0600 Subject: [PATCH 5/5] passing all tests --- hash_practice/exercises.py | 58 +++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/hash_practice/exercises.py b/hash_practice/exercises.py index b773537..fa110f2 100644 --- a/hash_practice/exercises.py +++ b/hash_practice/exercises.py @@ -1,3 +1,6 @@ +import collections +import heapq + def grouped_anagrams(strings): """ This method will return an array of arrays. Each subarray will have strings which are anagrams of each other @@ -17,47 +20,40 @@ def grouped_anagrams(strings): return list(anagrams_hash.values()) + def top_k_frequent_elements(nums, k): """ This method will return the k most common elements In the case of a tie it will select the first occuring element. - Time Complexity: ? - Space Complexity: ? + Time Complexity: Traversing through the list once to calculate the frequency, which is Linear O(N). + In addition, we're using heap to sort & find frequent words, which is Linear-Log O(NlogK) + where N is the number of items in the list -> overall time complexity O(NlogK) + Space Complexity: Linear O(N) - we're initializing new data structures """ - num_frequency = {} - frequency_dict = {} - for i in nums: - if i not in num_frequency: - num_frequency[i] = 1 - else: - num_frequency[i] += 1 - - for key, value in num_frequency.items(): - if value not in frequency_dict: - frequency_dict[value] = [key] - else: - frequency_dict[value].append(key) + if nums == []: + return [] - top_k_freq_ele = [] - for i in range(len(nums), 0, -1): - if i in top_k_freq_ele: - top_k_freq_ele.extend(frequency_dict[i]) - if len(top_k_freq_ele) >= k: - break + nums_dict = collections.defaultdict(int) + for n in nums: + nums_dict[n] += 1 - return top_k_freq_ele + output = [] + heap_list = [(-freq, key) for key, freq in nums_dict.items()] + heapq.heapify(heap_list) + + while(len(output) < k): + output.append(heapq.heappop(heap_list)[1]) + + return output -# helper functions for sudoku -# using sets, not hash tables +# 4 helper functions for sudoku def not_in_row(arr, row): - - # Set to store characters seen so far. + # Set to store characters seen so far temp_set = set() for i in range(0, 9): - # If already encountered before, - # return false + # If already encountered before, return false if arr[row][i] in temp_set: return False @@ -71,8 +67,7 @@ def not_in_row(arr, row): def not_in_col(arr, col): temp_set = set() for i in range(0, 9): - # If already encountered before, - # return false + # If already encountered before,return false if arr[i][col] in temp_set: return False @@ -89,8 +84,7 @@ def not_in_box(arr, startRow, startCol): for col in range(0, 3): curr = arr[row + startRow][col + startCol] - # If already encountered before, - # return false + # If already encountered before, return false if curr in temp_set: return False