diff --git a/dotfiles/lib/python/merge_sorted_linked_lists.py b/dotfiles/lib/python/merge_sorted_linked_lists.py new file mode 100644 index 00000000..ade71b8b --- /dev/null +++ b/dotfiles/lib/python/merge_sorted_linked_lists.py @@ -0,0 +1,59 @@ +import heapq + +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + +def merge_sorted_linked_lists(lists): + min_queue = [] + result = ListNode(None) + current_node = result + for list_index, alist in enumerate(lists): + if alist is None: + continue + heap_value = (alist.val, list_index) + lists[list_index] = alist.next + heapq.heappush(min_queue, heap_value) + + while min_queue: + value, list_index = heapq.heappop(min_queue) + selected_list = lists[list_index] + if selected_list is not None: + lists[list_index] = selected_list.next + heapq.heappush(min_queue, (selected_list.val, list_index)) + new_node = ListNode(value) + current_node.next = new_node + current_node = new_node + return result.next + + +def make_linked_list(*values): + result = None + for value in values[::-1]: + new_node = ListNode(value) + new_node.next = result + result = new_node + return result + + +def linked_list_to_list(ll): + result = [] + while ll: + result.append(ll.val) + ll = ll.next + return result + + +if __name__ == '__main__': + lists = [ + make_linked_list(1, 10, 20, 21), + make_linked_list(16, 17, 18, 22), + make_linked_list(12, 13, 24), + make_linked_list(-1, 15, 24), + make_linked_list(-4), + None, + ] + res = merge_sorted_linked_lists(lists) + print (linked_list_to_list(res)) + diff --git a/dotfiles/lib/python/quicksort.py b/dotfiles/lib/python/quicksort.py new file mode 100644 index 00000000..f4fbe833 --- /dev/null +++ b/dotfiles/lib/python/quicksort.py @@ -0,0 +1,36 @@ +def quicksort(incoming, lower=0, upper=None): + if upper is None: + upper = len(incoming) + if upper - lower < 2: + return + low_swap = lower + high_swap = upper - 1 + replacing = high_swap + pivot = incoming[high_swap] + high_swap -= 1 + while True: + if replacing > low_swap: + candidate = incoming[low_swap] + if candidate > pivot: + incoming[replacing] = candidate + replacing = low_swap + if low_swap == high_swap: + break + low_swap += 1 + else: + candidate = incoming[high_swap] + if candidate < pivot: + incoming[replacing] = candidate + replacing = high_swap + if low_swap == high_swap: + break + high_swap -= 1 + incoming[replacing] = pivot + quicksort(incoming, lower=lower, upper=replacing) + quicksort(incoming, lower=replacing+1, upper=upper) + + +if __name__ == '__main__': + my_list = [3, 20, 2, 52, 44, 16, 24, 5, 12, 4, 1, 14, 60, 29, 33, 1] + quicksort(my_list) + print(my_list) diff --git a/dotfiles/lib/python/skyline_problem.py b/dotfiles/lib/python/skyline_problem.py new file mode 100644 index 00000000..6b423eb7 --- /dev/null +++ b/dotfiles/lib/python/skyline_problem.py @@ -0,0 +1,49 @@ +import heapq + + +def get_skyline(buildings): + result = [] + active_buildings = [] + + last_index = -1 + + def add_entry(index, height): + last_height = result[-1][1] if result else 0 + if height != last_height: + result.append([index, height]) + + def handle_next_active_building(): + (negative_height, end_index) = heapq.heappop(active_buildings) + while active_buildings and active_buildings[0][1] <= end_index: + heapq.heappop(active_buildings) + new_height = -active_buildings[0][0] if active_buildings else 0 + add_entry(end_index, new_height) + + def add_entry_for_last(): + if active_buildings: + add_entry(last_index, -active_buildings[0][0]) + + for (left_index, right_index, height) in buildings: + + if last_index > -1 and left_index != last_index: + # We have to do this here inside this if statement to handle the + # case where multiple building (potentially having different + # heights) start on the same index. + add_entry_for_last() + + while active_buildings and active_buildings[0][1] < left_index: + handle_next_active_building() + + heapq.heappush(active_buildings, (-height, right_index)) + last_index = left_index + + add_entry_for_last() + + while active_buildings: + handle_next_active_building() + + return result + + +if __name__ == '__main__': + print(get_skyline([[1,9,10],[1,7,15],[5,12,12],[15,20,10],[19,24,8], [26, 100, 100]]))