Skip to content
Merged
Show file tree
Hide file tree
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
18 changes: 15 additions & 3 deletions algorithms/arrays/remove_duplicates.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@

Input: [1, 1 ,1 ,2 ,2 ,3 ,4 ,4 ,"hey", "hey", "hello", True, True]
Output: [1, 2, 3, 4, 'hey', 'hello']

Time Complexity: O(n) for hashable items, O(n²) worst case for unhashable items
Space Complexity: O(n) for the seen set and result array
"""

from collections.abc import Hashable


def remove_duplicates(array):
seen = set()
new_array = []

for item in array:
if item not in new_array:
new_array.append(item)
if isinstance(item, Hashable):
if item not in seen:
seen.add(item)
new_array.append(item)
else:
if item not in new_array:
new_array.append(item)

return new_array
return new_array
15 changes: 8 additions & 7 deletions algorithms/arrays/summarize_ranges.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@
For example, given [0, 1, 2, 4, 5, 7], return [(0, 2), (4, 5), (7, 7)].
"""

from typing import List, Tuple

from typing import List

def summarize_ranges(array: List[int]) -> List[str]:
def summarize_ranges(array: List[int]) -> List[Tuple[int, ...]]:
res = []
if len(array) == 0:
return []
if len(array) == 1:
return [str(array[0])]
return [(array[0], array[0])]
it = iter(array)
start = end = next(it)
for num in it:
if num - end == 1:
end = num
else:
res.append((start, end) if start != end else (start,))
res.append((start, end))
start = end = num
res.append((start, end) if start != end else (start,))
return [f"{r[0]}-{r[1]}" if len(r) > 1 else str(r[0]) for r in res]

res.append((start, end))
return res
3 changes: 1 addition & 2 deletions algorithms/graph/find_all_cliques.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
the subgraph there is an edge between them).
"""


def find_all_cliques(edges):
"""
takes dict of sets
Expand All @@ -15,9 +16,7 @@ def find_all_cliques(edges):
"""

def expand_clique(candidates, nays):
nonlocal compsub
if not candidates and not nays:
nonlocal solutions
solutions.append(compsub.copy())
else:
for selected in candidates.copy():
Expand Down
61 changes: 31 additions & 30 deletions algorithms/tree/construct_tree_postorder_preorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,87 +21,88 @@
Output: 8 4 9 2 5 1 6 3 7
"""


class TreeNode:

def __init__(self, val, left = None, right = None):
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right


pre_index = 0



def construct_tree_util(pre: list, post: list, low: int, high: int, size: int):
"""
Recursive function that constructs tree from preorder and postorder array.
preIndex is a global variable that keeps track of the index in preorder
array.
preorder and postorder array are represented are pre[] and post[] respectively.
low and high are the indices for the postorder array.
Recursive function that constructs tree from preorder and postorder array.

preIndex is a global variable that keeps track of the index in preorder
array.
preorder and postorder array are represented are pre[] and post[] respectively.
low and high are the indices for the postorder array.
"""

global pre_index

if pre_index == -1:
pre_index = 0


#Base case
if(pre_index >= size or low > high):

# Base case
if pre_index >= size or low > high:
return None

root = TreeNode(pre[pre_index])
pre_index += 1

#If only one element in the subarray return root
if(low == high or pre_index >= size):
# If only one element in the subarray return root
if low == high or pre_index >= size:
return root

#Find the next element of pre[] in post[]
# Find the next element of pre[] in post[]
i = low
while i <= high:
if(pre[pre_index] == post[i]):
if pre[pre_index] == post[i]:
break

i += 1

#Use index of element present in postorder to divide postorder array
#to two parts: left subtree and right subtree
if(i <= high):
# Use index of element present in postorder to divide postorder array
# to two parts: left subtree and right subtree
if i <= high:
root.left = construct_tree_util(pre, post, low, i, size)
root.right = construct_tree_util(pre, post, i+1, high, size)
root.right = construct_tree_util(pre, post, i + 1, high, size)

return root


def construct_tree(pre: list, post: list, size: int):
"""
Main Function that will construct the full binary tree from given preorder
and postorder array.
Main Function that will construct the full binary tree from given preorder
and postorder array.
"""

global pre_index
root = construct_tree_util(pre, post, 0, size-1, size)
root = construct_tree_util(pre, post, 0, size - 1, size)

return print_inorder(root)



def print_inorder(root: TreeNode, result = None):
def print_inorder(root: TreeNode, result=None):
"""
Prints the tree constructed in inorder format
Prints the tree constructed in inorder format
"""
if root is None:
return []
if result is None:
if result is None:
result = []

print_inorder(root.left, result)
result.append(root.val)
print_inorder(root.right, result)
return result

if __name__ == '__main__':

if __name__ == "__main__":
pre = [1, 2, 4, 5, 3, 6, 7]
post = [4, 5, 2, 6, 7, 3, 1]
size = len(pre)
Expand Down
Loading