代码改变世界

[LeetCode] 35. Search Insert Position_Easy tag: Binary Search

2018-08-29 10:34  Johnson_强生仔仔  阅读(210)  评论(0编辑  收藏  举报

 

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Example 1:

Input: [1,3,5,6], 5
Output: 2

Example 2:

Input: [1,3,5,6], 2
Output: 1

Example 3:

Input: [1,3,5,6], 7
Output: 4

Example 4:

Input: [1,3,5,6], 0
Output: 0

Update: 04/13/2019, 添加第4种方式,个人认为是面试过程中最适合用的。

Update: 08/11/2023, 添加第5种方式,比第四种更适合用。

思路就是Binary Search, 找到first position s.t A[i] >= target

Code

1) 利用python的built-in function     bisect.bisect_left

class Solution:
    def searchInsert(self, nums, target):
        return bisect.bisect_left(nums, target)

 

2) 利用python的built-in function     bisect.bisect

class Solution:
    def searchInsert(self, nums, target):
       return nums.index(target) if target  in nums else bisect.bisect(nums, target)

 

3) basic 做法, first position s.t A[i] >= target

        if not nums: return 0
        l, r = 0, len(nums)-1
        while l + 1 < r:
            mid = l + (r - l)//2
            if nums[mid] < target:
                l = mid
            elif nums[mid] > target:
                r = mid
            else:
                return mid  # 因为没有duplicates
        if nums[l] >= target:
            return l
        elif nums[r] >= target:
            return r
        else:
            return r+1  # 因为有可能比最大的还大

 

4) 还是用binary search的模板,只不过要注意左右边界,尤其是左边界时,如果小于或者等于nums中的最小值,都要返回0;但是右边界如果大于是len(n),如何是相等则是len(n)- 1。

class Solution:
    def searchInsert(self, nums, target):
        l, r = 0, len(nums) - 1
        if not nums or nums[l] >= target:
            return 0
        if nums[r] < target:
            return len(nums)
        while l + 1 < r:
            mid = l + (r - l)//2
            if nums[mid] > target:
                r = mid
            elif nums[mid] < target:
                l = mid
            else:
                return mid
        return r     # 这里直接return r 是因为边界已经考虑,所以最起始的r要么是等于target,要么是> target, 而l 也以为边界已经考虑的原因,
所以最起始的l肯定是小于target的,所以不可能是l(另外if语句里只有在nums[mid] < target 才会改变l)所以一定是r。

 5)还是用binary search 的模板,而且想清楚其实本质就是找first index >= target, 如果找不到那就返回len(nums)

class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        # first index >= nums, if none, then len(nums)
        l, r = 0, len(nums) - 1
        while l + 1 < r:
            mid = l + (r - l)//2
            num = nums[mid]
            if num >= target:
                r = mid
            else:
                l = mid
        if nums[l] >= target:
            return l
        elif nums[r] >= target:
            return r
        else:
            return len(nums)