Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 103 additions & 10 deletions hash_practice/exercises.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,103 @@
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
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note though, that the n you refer to is the number of letters in each word, not the number of words in the list (let's call that m). Since the O(n * log(n)) sorted call gets called m times, it would be more accurate to say that it is O(m * n * log(n)).

However, we can make a simplifying assumption. Given that we know the input is a list of English words, and that words in English don't get too large (about 5 letters per word on average), the effect of n is going to be dwarfed by the effect of m, the number of words in the list. After all, there may be hundreds or thousands of words in the list, but there are not going to be words of that size most likely.

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
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
"""
pass
if nums == []:
return []

nums_dict = collections.defaultdict(int)
for n in nums:
nums_dict[n] += 1

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


# 4 helper functions for sudoku
def not_in_row(arr, row):
# Set to store characters seen so far
temp_set = set()

for i in range(0, 9):

# If already encountered before, return false
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] != '.':
temp_set.add(arr[row][i])

return True

def not_in_col(arr, col):
temp_set = set()
for i in range(0, 9):
# If already encountered before,return false
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] != '.':
temp_set.add(arr[i][col])

return True

def not_in_box(arr, startRow, startCol):
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 temp_set:
return False

# If it is not an empty cell,
# insert value at current cell in set
if curr != '.':
temp_set.add(curr)

return True

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))


def valid_sudoku(table):
Expand All @@ -22,8 +106,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: ?
"""
pass
Time Complexity: Quadratic O(N^2) - nested for loop

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be true if we took in arbitrary nxn grids, but luckily since we only accept 3x3 grids, we can actually just say this is O(n)!

Space Complexity: Constant O(1) - not initializing any new data structures;
unless we're counting temp sets from our helper functions

"""
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 is_valid(table, i, j):
return False

return True