Search Insert Position

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.

Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0

终于开始入binary search的坑了。之前总是分不清结束条件,和结束之后左右index所在的位置,是时候搞定它了。
这道题还比较简单,属于binary serach 改动较小的。当然如果元素存在于数组中就是二分查找,如果元素不存在时,理想的情况时最终left和right可以把元素包括在其中。但是这种情况很理想。一种情况是,在更新mid时,直接将元素甩到了left和right的区域外面。这种情况下,因为元素已经在界外,mid元素会不断朝向 target逼近。最终left>right时,已经逼近在该元素附近。
 
具体分析参考Yanbing Shi博客一段解析:
Binary search的变种。如果target存在于数组中,则binary search就能找到。关键在于target不在数组中,当binary search结束时:start > end时,究竟应该如何获得插入位置。这里考察的是对base case的分析。定义insertion index为p,两种base case情况:
 
1. start = end = mid:
a. target < A[mid],则我们知道p = mid。
binary search下一步会搜索A[start = mid : end = mid-1]而终止,在这一步应该返回start。
b. 反之target > A[mid],则我们知道p = mid+1。
binary search下一步会搜索A[start = mid+1 : end = mid]而终止,这一步我们仍旧应该返回start。
 
2. start = end-1 = mid:
a. target < A[mid],则我们知道p = mid。
同1a情况,查找结束start > end时,返回start
b. target > A[mid],则我们知道p = mid+1或mid+2
binary search下一步会搜索A[start = mid+1 : end = mid+1],即base case 1的情况。
 
综上所述,该问题的解法思路如下:
1. Binary search整个数组,如果在start <= end时找到了target,返回mid
2. 如果查找失败,即start > end,返回start即可。
具体代码如下,时间复杂度O(logn),空间复杂度O(1).
class Solution(object):
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        if not nums:
            return 0 
        left = 0 
        right = len(nums)-1
        while (left <= right):
          mid = (left + right)>>1
          if nums[mid] == target:
              return mid
          else:
              if nums[mid] < target:
                  left = mid + 1
              else:
                  right = mid -1
        return left 
            

 另外一种解法,不需要担心将原本在其中的元素甩出区间。不使用mid-1和mid+1。最后需要判断最后得到的2个值(或者开始是一个值则是一个值)的区间和target的情况,可以参考九章的代码,但是这个“find the first position >= target”和find the last position < target, return +1,个人感觉没有多大差别。

代码如下:

class Solution(object):
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        if not nums:
            return 0
            
        l = 0
        r = len(nums)-1
        while l+1 < r:
            mid = l+(r-l)/2
            if nums[mid] == target:
                return mid
            if nums[mid] > target:
                r = mid
            else:
                l = mid
        if nums[l]<target<=nums[r]:
           return r
        elif nums[l]>=target:
           return l
        else:
             return r+1
        

 

原文地址:https://www.cnblogs.com/sherylwang/p/5487699.html