Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the binary search exercises #2039

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
50 changes: 50 additions & 0 deletions 2dmatrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# The code defines a searchMatrix method to locate a target value within a 2D matrix.
# The matrix has sorted properties: each row is sorted from left to right, and the last element of each row is less than or equal to the first element of the next row.
#
# The search is conducted in two phases:
# 1. Locate the correct row where the target might be present:
# - Two pointers, 'top' and 'bot', represent the range of rows to consider.
# - A binary search is performed over the rows:
# - If the target is greater than the last element of the current row (matrix[row][-1]), the search moves down by setting top = row + 1.
# - If the target is less than the first element of the current row (matrix[row][0]), the search moves up by setting bot = row - 1.
# - If the target is within the current row range, we break out to proceed with a search within this row.
# - If no such row is found, the method returns False, as the target is not in the matrix.
#
# 2. Perform binary search within the identified row:
# - Two pointers, 'l' and 'r', define the search range within the row.
# - If matrix[row][m] (mid-point element) equals the target, True is returned.
# - If matrix[row][m] is less than the target, l is updated to m + 1 to search the right half of the row.
# - If matrix[row][m] is greater than the target, r is updated to m - 1 to search the left half of the row.
# If the target is not found after both searches, the method returns False.
#
# TC: O(log m + log n) - Binary search over rows (log m) and columns (log n).
# SC: O(1) - Constant space is used, as only pointers are maintained for each binary search step.


class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
ROWS, COLS = len(matrix), len(matrix[0])

top, bot = 0, ROWS - 1
while top <= bot:
row = (top + bot) // 2
if target > matrix[row][-1]:
top = row + 1
elif target < matrix[row][0]:
bot = row - 1
else:
break

if not (top <= bot):
return False
row = (top + bot) // 2
l, r = 0, COLS - 1
while l <= r:
m = (l + r) // 2
if target > matrix[row][m]:
l = m + 1
elif target < matrix[row][m]:
r = m - 1
else:
return True
return False
40 changes: 40 additions & 0 deletions rotated.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# The code defines a search method to find a target value in a rotated sorted array using binary search.
# The array is sorted but rotated, meaning it was initially sorted and then rotated at some pivot unknown to us.
# Two pointers, 'l' and 'r', are used to represent the left and right boundaries of the current search space.
#
# In each iteration:
# - The mid-point (mid) is calculated to divide the array in half.
# - If nums[mid] equals the target, mid is returned as the index where the target is found.
# - If the left half (from nums[l] to nums[mid]) is sorted:
# - If the target lies within this sorted half (target >= nums[l] and target < nums[mid]), we narrow the search to this half by setting r = mid - 1.
# - Otherwise, we search the right half by setting l = mid + 1.
# - If the right half (from nums[mid] to nums[r]) is sorted:
# - If the target lies within this sorted half (target > nums[mid] and target <= nums[r]), we search this half by setting l = mid + 1.
# - Otherwise, we narrow the search to the left half by setting r = mid - 1.
# If the target is not found after the loop, -1 is returned, indicating it is not present in the array.
#
# TC: O(log n) - Binary search halves the search space each iteration.
# SC: O(1) - Constant space usage, as only pointers for the search range and mid-point are maintained.


class Solution:
def search(self, nums: List[int], target: int) -> int:
l, r = 0, len(nums) - 1

while l <= r:
mid = (l + r) // 2
if target == nums[mid]:
return mid

if nums[l] <= nums[mid]:
if target > nums[mid] or target < nums[l]:
l = mid + 1
else:
r = mid - 1

else:
if target < nums[mid] or target > nums[r]:
r = mid - 1
else:
l = mid + 1
return -1
29 changes: 29 additions & 0 deletions unknown_size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# The code implements a search algorithm for an unknown-sized, sorted array using an external interface 'ArrayReader'.
# The search method utilizes binary search to efficiently locate the target value within the array.
# An initial left (l) and right (r) boundary is set, where:
# - 'l' starts at index 0.
# - 'r' is obtained through reader.get(-1), which is assumed to return the size or a boundary of the array.
# In each iteration, the mid-point (mid) is calculated to split the search space:
# - If reader.get(mid) equals the target, mid is returned as the index where the target is found.
# - If reader.get(mid) is greater than the target, the search shifts to the left half by setting r = mid - 1.
# - Otherwise, it shifts to the right half by setting l = mid + 1.
# If the target is not found after the loop, -1 is returned, indicating the target does not exist in the array.
#
# TC: O(log n) - Since binary search reduces the search space by half each iteration.
# SC: O(1) - Constant space is used, as only pointers for the search range and mid-point are maintained.


class Solution:
def search(self, reader: 'ArrayReader', target: int) -> int: # type: ignore
l, r = 0, reader.get(-1)
print(r)
while l <= r:
mid = (l + r) // 2
if reader.get(mid) == target:
return mid
elif reader.get(mid) > target:
r = mid - 1
else:
l = mid + 1
return -1