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

complete binary search 1 #2010

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
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/Binary-Search-1.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ Search a 2D Matrix(https://leetcode.com/problems/search-a-2d-matrix/)
Search in a Rotated Sorted Array (https://leetcode.com/problems/search-in-rotated-sorted-array/)




## Problem3
Search in Infinite sorted array:

Expand Down
52 changes: 52 additions & 0 deletions rotated_sorted_array.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import List


class Solution:
def linear_search(self, nums: List[int], target: int) -> int:
"""
This method search for the target using linear search.
Edge Case: target may or may not be found, array is empty, number of elements in the array is 1
:param nums: array of integers that is search space
:param target: integer to find
:return: index of target if found else -1
Takes O(n) time since whole array is traversed.
"""
for idx, num in enumerate(nums):
if num == target:
return idx

return -1

def search(self, nums: List[int], target: int) -> int:
"""
This method search for the target using binary search.
The idea is: (1) wherever mid lands one portion (left or right) of the array will always be sorted.
(2) Identify which half of the array is sorted
(3) Since sorted array gives a range we can check if the target lies in the range.
(4) update lo and hi accordingly
:param nums: array of integers that is search space
:param target:integer to search
:return:index of target if found else -1
"""
lo = 0
hi = len(nums) - 1
while lo <= hi:
mid = lo + (hi - lo) // 2
if target == nums[mid]:
return mid

elif nums[mid] < nums[hi]: # left sorted
if target > nums[mid] >= target:
lo = mid + 1
else:
hi = mid - 1

else: # right sorted
if nums[lo] <= target < nums[mid]:
hi = mid - 1
else:
lo = mid + 1


obj = Solution()
print(obj.search([4, 5, 6, 7, 0, 1, 1, 2], 4))
74 changes: 74 additions & 0 deletions search_2d_martix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from typing import List


# Todo: solution with O(log (m*n)) or O(log m + log n)
class Solution:
def brute_force_searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
"""
Use linear search to find the target in matrix
:param matrix: 2-D matrix
:param target: to search
:return: True if target found else False
Runs in O(n) time complexity
"""
num_rows = len(matrix)
num_cols = len(matrix[0])

for r in range(num_rows):
for c in range(num_cols):
if matrix[r][c] == target:
return True

return False

def binary_search(self, matrix, r, c, target):
lo = 0
hi = c

while lo <= hi:
mid = lo + (hi - lo) // 2
if matrix[r][mid] == target:
return True
elif matrix[r][mid] < target:
lo = mid + 1
else:
hi = mid - 1

def searchMatrix_1(self, matrix: List[List[int]], target: int) -> bool:
"""
This is O( m + log(n)) solution
The idea is for each row find if target lies there and then do the binary search on that row.
Note reverse is not possible O( n + log(m)) meaning search for col which have target and then do
binary search on that row.
:param matrix: 2-D matrix
:param target: to search
:return: True if target found else False
"""
num_rows = len(matrix)
num_cols = len(matrix[0])

for r in range(num_rows):
if target <= matrix[r][num_cols - 1]: # check if target is in this row
is_found = self.binary_search(matrix, r, num_cols - 1, target)
return is_found

def searchMatrix_2(self, matrix: List[List[int]], target: int) -> bool:
"""
This is O( m * log(n)) / O( n * log(m)) solution
The idea is to check if the target is in a row using binary search
Note: check in each column can be done
:param matrix: 2-D matrix
:param target: to search
:return: True if target found else False
"""
num_rows = len(matrix)
num_cols = len(matrix[0])

for r in range(num_rows):
is_found = self.binary_search(matrix, r, num_cols - 1, target)
return is_found


obj = Solution()
ans = obj.searchMatrix_2([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 60]], 3)
print(ans)
83 changes: 83 additions & 0 deletions search_sortd_arr_unknown_size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# """
# This is ArrayReader's API interface.
# You should not implement it, or speculate about its implementation
# """
# class ArrayReader:
# def get(self, index: int) -> int:

class Solution:
def linear_search(self, reader: 'ArrayReader', target: int) -> int:
"""
This is linear search with O(n) time complexity
:param reader: API
:param target: target to search in sorted array of unknown size
:return: True if target exists else false
"""
idx = 0
while True:
el = reader.get(idx)
if el == target:
return idx
if el == pow(2, 31) - 1:
return -1

idx += 1

def binary_search(self, reader, target, lo, hi):
"""
This method implements binary search
:param reader: API
:param target: to search
:param lo: lower bound for binary search
:param hi: upper bound for binary search
:return: index of element in sorted array or -1 if not found
"""
while lo <= hi:
mid = lo + (hi - lo) // 2
el = reader.get(mid)
if el == target:
return mid

elif el < target:
lo = mid + 1

elif el > target:
hi = mid - 1

return -1

def binary_search_1(self, reader: 'ArrayReader', target: int) -> int:
"""
This is binary search with O(log n) time complexity. The upper bound of binary search in this method
is pow(2,31). What if the array size is 10 then a significant number of iterations will be of no use.
Thus, its better to find the range in which target may exist. Implemented in binary_search_2() method.
:param reader: API to get element at index i
:param target: target to search in sorted array of unknown size
:return: idx if target exists else -1
"""
lo = 0
hi = pow(2, 31) - 1

idx = self.binary_search(reader, target, lo, hi)
return idx

def binary_search_2(self, reader: 'ArrayReader', target: int) -> int:
"""
This is binary search with O(log n) time complexity. First we find the range in which the target exists using
binary search.
Then use binary search to find the target index.
:param reader: API to get element at index i
:param target: target to search in sorted array of unknown size
:return: idx if target exists else -1
"""
lo = 0
hi = 1

while target > reader.get(hi):
lo = 0
# since hi is multiplied by 2, it is binary search. Meaning search space increases 2 times in each iteration
# If multiplied by 3 it won't be binary search. TC: O(log base 3 n)
hi = 2 * hi

idx = self.binary_search(reader, target, lo, hi)
return idx