Skip to content
Open
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
138 changes: 116 additions & 22 deletions Exercise_1.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,116 @@
# Python code to implement iterative Binary
# Search.

# It returns location of x in given array arr
# if present, else returns -1
def binarySearch(arr, l, r, x):

#write your code here



# Test array
arr = [ 2, 3, 4, 10, 40 ]
x = 10

# Function call
result = binarySearch(arr, 0, len(arr)-1, x)

if result != -1:
print "Element is present at index % d" % result
else:
print "Element is not present in array"
# Python code to implement iterative Binary
# Search.

# It returns location of x in given array arr
# if present, else returns -1
"""
Time Complexity: O(log n) since we are dividing the array into half in each iteration.
Space Complexity: O(1) since we are not using any extra space or any other data structure.

Did this code successfully run on Leetcode : Yes (Problem: 704. Binary Search)
Approach:
1. We will use two pointers left and right to keep track of the current search space.
2. We will calculate the mid index and compare the mid element with the target value x.
3. If the mid element is equal to x, we return the mid index.
4. If the mid element is less than x, we move the left pointer to mid + 1 to search in the right half of the array.
5. If the mid element is greater than x, we move the right pointer to mid - 1 to search in the left half of the array.
6. We repeat steps 2-5 until the left pointer is less than or equal to the right pointer. If we exit the loop without finding x, we return -1 indicating that x is not present in the array.
"""


def binarySearch(arr, l, r, x):

# write your code here
# Handling edge cases
if arr is None or len(arr) == 0:
return -1
left = 0
right = len(arr) - 1
while left <= right:
# To avoid integer overflow use left + (right - left) // 2 instead of (left + right) // 2
mid = left + (right - left) // 2
if arr[mid] == x:
return mid
elif arr[mid] < x:
left = mid + 1
else:
right = mid - 1
return -1


def run_tests():
"""A small test suite covering typical, edge, and boundary cases."""

# 1. Original example: element present in the middle-ish of the array
arr = [2, 3, 4, 10, 40]
assert binarySearch(arr, 0, len(arr) - 1, 10) == 3, "element present (10)"

# 2. Element is the first item
arr = [2, 3, 4, 10, 40]
assert binarySearch(arr, 0, len(arr) - 1, 2) == 0, "element is first item"

# 3. Element is the last item
arr = [2, 3, 4, 10, 40]
assert binarySearch(arr, 0, len(arr) - 1, 40) == 4, "element is last item"

# 4. Element not present (falls between two values)
arr = [2, 3, 4, 10, 40]
assert binarySearch(arr, 0, len(arr) - 1, 5) == -1, "element not present (between values)"

# 5. Element smaller than everything in the array
arr = [2, 3, 4, 10, 40]
assert binarySearch(arr, 0, len(arr) - 1, 1) == -1, "element smaller than min"

# 6. Element larger than everything in the array
arr = [2, 3, 4, 10, 40]
assert binarySearch(arr, 0, len(arr) - 1, 100) == -1, "element larger than max"

# 7. Empty array
arr = []
assert binarySearch(arr, 0, -1, 5) == -1, "empty array"

# 8. None array (edge case handled explicitly in the function)
assert binarySearch(None, 0, -1, 5) == -1, "None array"

# 9. Single-element array, element present
arr = [7]
assert binarySearch(arr, 0, 0, 7) == 0, "single element, present"

# 10. Single-element array, element absent
arr = [7]
assert binarySearch(arr, 0, 0, 3) == -1, "single element, absent"

# 11. Two-element array, both possibilities
arr = [1, 5]
assert binarySearch(arr, 0, 1, 1) == 0, "two elements, find first"
assert binarySearch(arr, 0, 1, 5) == 1, "two elements, find second"
assert binarySearch(arr, 0, 1, 3) == -1, "two elements, not found"

# 12. Larger array with even length
arr = list(range(0, 100, 2)) # [0, 2, 4, ..., 98]
assert binarySearch(arr, 0, len(arr) - 1, 50) == 25, "large even-length array, present"
assert binarySearch(arr, 0, len(arr) - 1, 51) == -1, "large even-length array, absent (odd number)"

# 13. Negative numbers
arr = [-20, -10, -5, 0, 5, 10]
assert binarySearch(arr, 0, len(arr) - 1, -10) == 1, "negative numbers, present"
assert binarySearch(arr, 0, len(arr) - 1, -1) == -1, "negative numbers, absent"

print("All tests passed!")


if __name__ == "__main__":
# Test array
arr = [2, 3, 4, 10, 40]
x = 10

# Function call
result = binarySearch(arr, 0, len(arr) - 1, x)

if result != -1:
print("Element is present at index % d" % result)
else:
print("Element is not present in array")

print("\nRunning test suite...\n")
run_tests()
133 changes: 110 additions & 23 deletions Exercise_2.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,110 @@
# Python program for implementation of Quicksort Sort

# give you explanation for the approach
def partition(arr,low,high):


#write your code here


# Function to do Quick sort
def quickSort(arr,low,high):

#write your code here

# Driver code to test above
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr,0,n-1)
print ("Sorted array is:")
for i in range(n):
print ("%d" %arr[i]),


# Python program for implementation of Quicksort Sort
"""
Time Complexity: O(n log n) on average, O(n^2) in worst case)
Space Complexity: O(n) in worst case due to recursion stack, O(log n) on average.

Did this code successfully run on Leetcode : Yes (Problem: 912. Sort an Array)

Approach:

I have implemented the quicksort using Median-of-three pivot selection
and partitioning the array into two halves based on the pivot (Standard Lomuto Partitioning).
The algorithm recursively sorts the left and right halves of the array until the entire array is sorted.


The use of the median-of-three pivot selection helps
to reduce the likelihood of encountering the worst-case scenario with
Standard lomuto partitioning based pivot selection, which can occur when
the pivot is consistently chosen poorly especially for already sorted,
reverse sorted or nearly sorted arrays.
"""

def median_of_three(arr, low, high):
# Sort arr[low], arr[mid], arr[high] in place so arr[mid] ends up the median
mid = low + (high - low) // 2
if arr[low] > arr[mid]:
arr[low], arr[mid] = arr[mid], arr[low]
if arr[low] > arr[high]:
arr[low], arr[high] = arr[high], arr[low]
if arr[mid] > arr[high]:
arr[mid], arr[high] = arr[high], arr[mid]
return mid # Return the index of the median value


def partition(arr, low, high):

mid = median_of_three(arr, low, high)

# Swap the median value with the last element to use it as the pivot
arr[mid], arr[high] = arr[high], arr[mid]
pivot = arr[high]

# Standard Lomuto partitioning
i = low - 1

for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1


# Function to do Quick sort
def quickSort(arr, low=0, high=None):
if high is None:
high = len(arr) - 1
if low >= high or low < 0:
return arr
if low < high:
pivot_index = partition(arr, low, high)
# Recursively sort elements before partition and after partition
quickSort(arr, low, pivot_index - 1)
quickSort(arr, pivot_index + 1, high)
return arr


def run_tests():
# Original driver example
assert quickSort([10, 7, 8, 9, 1, 5]) == [1, 5, 7, 8, 9, 10]

# Empty array
assert quickSort([]) == []

# Single element
assert quickSort([1]) == [1]

# Two elements
assert quickSort([2, 1]) == [1, 2]

# Already sorted
assert quickSort([1, 2, 3, 4, 5]) == [1, 2, 3, 4, 5]

# Reverse sorted
assert quickSort([5, 4, 3, 2, 1]) == [1, 2, 3, 4, 5]

# All duplicates
assert quickSort([3, 3, 3, 3]) == [3, 3, 3, 3]

# Duplicates mixed in
assert quickSort([4, 2, 2, 8, 4, 1]) == [1, 2, 2, 4, 4, 8]

# Negative numbers
assert quickSort([-5, 3, -2, 0, 8, -1]) == [-5, -2, -1, 0, 3, 8]

# Duplicates + negatives
assert quickSort([9, -3, 7, 0, 0, -3, 9]) == [-3, -3, 0, 0, 7, 9, 9]

print("All tests passed!")


if __name__ == "__main__":
run_tests()

print("\nDriver code demo:")
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr, 0, n - 1)
print("Sorted array is:")
for i in range(n):
print("%d" % arr[i])
Loading