Skip to content

Commit

Permalink
Merge pull request #2 from esramish/problem-257-optimization
Browse files Browse the repository at this point in the history
Added optimized solution for #257
  • Loading branch information
WHAHA-HA committed Jun 16, 2022
2 parents 6794f83 + 0de9bfd commit 182d2d7
Showing 1 changed file with 60 additions and 4 deletions.
64 changes: 60 additions & 4 deletions Solutions/257.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
[3, 7, 5, 6, 9], you should return (1, 3).
"""


from time import perf_counter
from random import randint
from typing import List, Tuple


Expand All @@ -26,15 +27,70 @@ def get_sort_range(arr: List[int]) -> Tuple[int, int]:
return start, end


def get_sort_range_optimized(arr: List[int]) -> Tuple[int, int]:
# Find rightmost possible index of left bound
left = 0
while left < len(arr) - 1 and arr[left] < arr[left + 1]:
left += 1

# Check if sorted
if left == len(arr) - 1:
return -1, -1

# Find leftmost possible index of right bound
right = len(arr) - 1
while right > 0 and arr[right] > arr[right - 1]:
right -= 1

# Find the minimum and the maximum of the current window
i = left + 1
min_val = max_val = arr[left]
while i <= right:
if arr[i] < min_val:
min_val = arr[i]
if arr[i] > max_val:
max_val = arr[i]
i += 1

# Expand the window leftwards to include all elements greater than the min,
# so that everything remaining to the left is less than the smallest element to the right
while left > 0 and arr[left - 1] > min_val:
left -= 1

# Expand the window rightwards to include all elements less than the max,
# so that everything remaining to the right is greater than the largest element to the left
while right < len(arr) - 1 and arr[right + 1] < max_val:
right += 1

return left, right


def print_both(arr: List[int]) -> None:
for f in [get_sort_range, get_sort_range_optimized]:
start = perf_counter()
result = f(arr)
end = perf_counter()
print(f"{result} ({end - start:.3} sec)")


if __name__ == "__main__":
print(get_sort_range([3, 5, 6, 7, 9]))
print(get_sort_range([3, 7, 5, 6, 9]))
print(get_sort_range([5, 4, 3, 2, 1]))
print_both([3, 5, 6, 7, 9])
print_both([3, 7, 5, 6, 9])
print_both([5, 4, 3, 2, 1])
print_both([0, 1, 3, 4, 2, 7, 5, 6, 8, 9])
print_both(
[0] + list([randint(1, 10**7 - 1) for _ in range(10**7 - 1)]) + [10**7]
) # Expecting (1, 9999999)


"""
SPECS:
get_sort_range:
TIME COMPLEXITY: O(n x log(n))
SPACE COMPLEXITY: O(n)
get_sort_range_optimized:
TIME COMPLEXITY: O(n)
SPACE COMPLEXITY: O(1) (auxiliary)
"""

0 comments on commit 182d2d7

Please sign in to comment.