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
Binary file added .DS_Store
Binary file not shown.
47 changes: 47 additions & 0 deletions problem1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
""""
We do a two binary search here, first for finding the first occurence and second one for the second occurene,
if nums[mid] = target, we will return m, but only if there doesnt exist any element previous to it (on the left side) and if there exists, it shoulndt be equal to the target.
do a regular binary search halving then if the mid != target. Do a similar approach for last occurence and shift pointers accordingly
TC for this is O(logn + logn) which is o(logn) plus constant time for calculating whether the mid - 1 and mid + 1 is equal to target or not. Also constant space.
"""

class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
def binarysearchFirst(nums, target, l, r):
while l <= r:
m = l +( r - l) // 2
if nums[m] == target:
if ( m == 0 or nums[m - 1] != target ):
return m
else:
r = m - 1
elif nums[m] > target:
r = m -1
else:
l = m + 1
return -1
def binarysearchLast(nums, target, l, r):
while l <= r:
m = l + ( r - l) // 2
if nums[m] == target:
if (m == len(nums) - 1 or nums[m + 1] != target ):
return m
else:
l = m + 1
elif nums[m] > target:
r = m -1
else:
l = m + 1
return -1

firstidx = binarysearchFirst(nums, target, 0, len(nums)-1)
if firstidx == -1:
return [-1, -1]
lastidx = binarysearchLast(nums, target, firstidx, len(nums) -1)
return [firstidx, lastidx]

21 changes: 21 additions & 0 deletions problem2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
if the nums at m is greater than the rightmost element, it is the wrapped around part and hence we can find the minimn in the rightmost part, else in the left part
the TC for this is o(logn) as during each iteration, the search space is halved. The sc is contant space as we dont store anything apart from the answer
"""

class Solution(object):
def findMin(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l , r = 0, len(nums) - 1

while l < r:
m = (l+r) // 2

if nums[m] > nums[r]: #the number lies in the right half (since rotation wraps around)
l = m + 1
else: #the number lies in the left side and m can still be a possible asnwer, hence we dont skip over m
r = m
return nums[l]
22 changes: 22 additions & 0 deletions problem3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
the tc for this solution if O(logn) as the search space is halved in each iteration, we check that if the num[mid] is less than the num[mid + 1], then we arein increasing slope and we can find he peak at right side,
else if there is a drop, we can find the peak either way
if the num[m] is not less than the num[mid + 1] we are bit above in the peak, so we move our search space to left, and not loose the mid, bcz it can petentially be our peak
the sc for this is O(1) as we dont use additional space"""


class Solution(object):
def findPeakElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l, r = 0, len(nums) - 1

while l < r:
m = l + (r - l)//2
if nums[m + 1] > nums[m]: #peak is at the right side, bcz intuitively, numbers are either rising, or will have a drop, either ways, we can find a peak
l = m + 1
else:
r = m # we dont want to loose m, bcz m could be our potential peak, hence not takinf m-1 but m
return r