From 96df906e7a99fc6bcf20da97702a9642dde1d37c Mon Sep 17 00:00:00 2001 From: Vaibhav Singh <45447817+itsvaibhav01@users.noreply.github.com> Date: Fri, 27 Mar 2020 12:46:07 +0530 Subject: [PATCH] All suggeted changes within additional time limit tests (#1815) * With all suggested changes :white_check_mark: possibly covered all the recommended guidelines * Updated with both slow and faster algorithms possibally covered all the recomendations * removed the time comparision part! * Update data_structures/stacks/next_greater_element.py Co-Authored-By: Christian Clauss * Update data_structures/stacks/next_greater_element.py Co-Authored-By: Christian Clauss * Update data_structures/stacks/next_greater_element.py Co-Authored-By: Christian Clauss * Update data_structures/stacks/next_greater_element.py Co-Authored-By: Christian Clauss * Add benchmark using timeit https://docs.python.org/3/library/timeit.html The performance delta between these two implementation is quite small... ``` next_greatest_element_slow(): 1.843442126 next_greatest_element(): 1.828941414 ``` * Optimize slow() to create fast() - Three algorithms in the race Three algorithms in the race * Use a bigger test array with floats, negatives, zero * Setup import next_greatest_element_fast Co-authored-by: Christian Clauss --- .../stacks/next_greater_element.py | 94 +++++++++++++++---- 1 file changed, 78 insertions(+), 16 deletions(-) diff --git a/data_structures/stacks/next_greater_element.py b/data_structures/stacks/next_greater_element.py index 29a039b96..4b400334e 100644 --- a/data_structures/stacks/next_greater_element.py +++ b/data_structures/stacks/next_greater_element.py @@ -1,24 +1,86 @@ -def printNGE(arr): - """ - Function to print element and Next Greatest Element (NGE) pair for all elements of list - NGE - Maximum element present afterwards the current one which is also greater than current one - >>> printNGE([11,13,21,3]) - 11 -- 13 - 13 -- 21 - 21 -- -1 - 3 -- -1 - """ - for i in range(0, len(arr), 1): +arr = [-10, -5, 0, 5, 5.1, 11, 13, 21, 3, 4, -21, -10, -5, -1, 0] +def next_greatest_element_slow(arr): + """ + Function to get Next Greatest Element (NGE) pair for all elements of list + Maximum element present afterwards the current one which is also greater than current one + >>> next_greatest_element_slow(arr) + [-5, 0, 5, 5.1, 11, 13, 21, -1, 4, -1, -10, -5, -1, 0, -1] + """ + result = [] + for i in range(0, len(arr), 1): next = -1 for j in range(i + 1, len(arr), 1): if arr[i] < arr[j]: next = arr[j] break - - print(str(arr[i]) + " -- " + str(next)) + result.append(next) + return result -# Driver program to test above function -arr = [11, 13, 21, 3] -printNGE(arr) +def next_greatest_element_fast(arr): + """ + Like next_greatest_element_slow() but changes the loops to use + enumerate() instead of range(len()) for the outer loop and + for in a slice of arr for the inner loop. + >>> next_greatest_element_fast(arr) + [-5, 0, 5, 5.1, 11, 13, 21, -1, 4, -1, -10, -5, -1, 0, -1] + """ + result = [] + for i, outer in enumerate(arr): + next = -1 + for inner in arr[i + 1:]: + if outer < inner: + next = inner + break + result.append(next) + return result + + +def next_greatest_element(arr): + """ + Function to get Next Greatest Element (NGE) pair for all elements of list + Maximum element present afterwards the current one which is also greater than current one + + Naive way to solve this is to take two loops and check for the next bigger number but that will make the + time complexity as O(n^2). The better way to solve this would be to use a stack to keep track of maximum + number givig a linear time complex solution. + + >>> next_greatest_element(arr) + [-5, 0, 5, 5.1, 11, 13, 21, -1, 4, -1, -10, -5, -1, 0, -1] + """ + stack = [] + result = [-1]*len(arr) + + for index in reversed(range(len(arr))): + if len(stack): + while stack[-1] <= arr[index]: + stack.pop() + if len(stack) == 0: + break + + if len(stack) != 0: + result[index] = stack[-1] + + stack.append(arr[index]) + + return result + + +if __name__ == "__main__": + from doctest import testmod + from timeit import timeit + + testmod() + print(next_greatest_element_slow(arr)) + print(next_greatest_element_fast(arr)) + print(next_greatest_element(arr)) + + setup = ("from __main__ import arr, next_greatest_element_slow, " + "next_greatest_element_fast, next_greatest_element") + print("next_greatest_element_slow():", + timeit("next_greatest_element_slow(arr)", setup=setup)) + print("next_greatest_element_fast():", + timeit("next_greatest_element_fast(arr)", setup=setup)) + print(" next_greatest_element():", + timeit("next_greatest_element(arr)", setup=setup))