Skip to content

Completed Binary Search-1 #2339

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

Open
wants to merge 2 commits 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
43 changes: 43 additions & 0 deletions search-2D-matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
https://leetcode.com/problems/search-a-2d-matrix/description/

The matrix looks like a row-wise flattened sorted 1D array. A “flattened sorted array” matrix is globally sorted when laid out as a 1D array from top-left to bottom-right.
--> Integers in each row are sorted left to right (or right to left).
--> The first integer of each row is greater than the last integer of the previous row.
We can treat it as a 1D array of m*n elements. 2D to 1D mapping -->
row = index // n (columns) --> How many full rows before this index as after every n elements, a new row starts
col = index % n --> How far into that row

Column-wise flattened array will not have the pre-requisite where the first integer of each col is greater than the last integer of the previous col. So, it is not globally sorted when flattened and we cannot use binary search to find an element. 2D to 1D mapping -->
row = index % m (rows)
col= index // m

Time Complexity: O(logmn)
Space Complexity: O(1)
"""

class Solution:
def searchMatrix(self, matrix, target):
m = len(matrix)
n = len(matrix[0])
low = 0
high = (m*n) - 1

while low <= high: # searching for element, so include low == high, which means a single element list
mid = (low + high)//2
row = mid // len(matrix[0])
col = mid % len(matrix[0])

if matrix[row][col] == target:
return True
elif target > matrix[row][col]:
low = mid + 1
elif target < matrix[row][col]:
high = mid - 1
return False


matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]]
target = 3
sol = Solution()
print(sol.searchMatrix(matrix, target))
52 changes: 52 additions & 0 deletions search-rotated-sorted-array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
https://leetcode.com/problems/search-in-rotated-sorted-array/description/

A classical binary search dies because the array isn’t globally sorted, but one of the two halves around mid always is sorted. At each step we can decide:
Which half is sorted?
If nums[L] <= nums[M], left side is sorted; else the right side is sorted.
Is target inside that sorted half’s range?
If yes, shrink into that half; otherwise dive into the other half.

Same logic is applied when the array is reverse sorted.

Edge cases:
empty array
length 1
target equals 1st, last or mid element

Time Complexity:O(logn)
Space Complexity: O(1)
"""

class Solution:
def search(self, nums, target):
if len(nums) == 0:
return -1

low = 0
high = len(nums) - 1

while low <= high:
mid = (high + low)//2

if nums[mid] == target:
return mid

if nums[low] <= nums[mid]: #LHS is sorted
if nums[low] <= target < nums[mid]: #searching in sorted LHS
high = mid - 1
else:
low = mid + 1 #switch to unsorted RHS
else:
if nums[mid] <= nums[high]: #RHS is sorted
if nums[mid] < target <= nums[high]: #searching in sorted RHS
low = mid + 1
else:
high = mid - 1 #switch to unsorted LHS.
return -1


nums = [4,5,6,7,0,1,2]
target = 3
sol = Solution()
print(sol.search(nums, target))
37 changes: 37 additions & 0 deletions search-sorted-array-unknown-size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
https://leetcode.com/problems/search-in-a-sorted-array-of-unknown-size/description/

Sorted array of unknown size. You don't know the length of the array. Brute force is linear probe but the length of array can be too large.
Exponential Search --> optimal search. Find the boundaries.

Edge case:
1. element not present
2. 1 element

Time Complexity: O(2logp) = O(logp) where p is the position of the target
Space Complexity: O(1)
"""

class Solution:
def search(self, reader, target):
low = 0
high = 1

# O(logp)
while reader.get(high) < target: # Find the search boundaries using exponential search
low = high
high = high * 2 # You double the size of the search range. You cut the number of steps needed in half, compared to walking linearly.

# O(logp)
while low <= high: # Binary Search on the boundaries
mid = (low + high)//2

if reader.get(mid) == target:
return mid

if target > reader.get(mid):
low = mid + 1

if target < reader.get(mid):
high = mid - 1
return -1