美文网首页
Leetcode--Binary Search

Leetcode--Binary Search

作者: Morphiaaa | 来源:发表于2017-03-11 01:07 被阅读0次

    4. Median of Two Sorted Arrays

    We can use the method that find the k-th samallest element in two sorted list to solve this problem.
    In this question, if the total length of this two list is odd, then the median will be the k-th smallest element (len(nums1)+len(nums2))/2
    if the total length is even, then the median will be
    (l/2-th element + l/2-1-th element)/2
    思路就是转换成求两个有序序列中的第k小元素。
    如果总长度为偶数,就是求第总长度/2 小的数
    如果总长度为奇数,就是求
    (第总长度/2 + 第总长度/2 -1)/2
    求第K小元素时,
    if not n1: return n2[k] if not n2: return n1[k]
    先找出两个有序序列的第l/2小的元素,即他们的中位数,将l1 + l2和k比较,如果大于等于k, 就在前半部分找。再继续判断median1和median2的大小,如果m1>m2,我们就舍弃m1的后半段
    return self.kthsmall(n1[:l1], n2, k)
    否则就舍弃n2的后半段,注意这里K不变,因为舍弃的长度在K之外。
    如果l1+l2小于K的话,我们就在后半段找,需要舍弃前边段。
    如果m1>m2: return self.kthsmall(n1, n2[l2+1:], k-l2-1)
    否则:return self.kthsmall(n1[l1+1:], n2, k-l1-1 )
    注意这里要对k进行更新,因为舍弃的长度也包含在k里

    33. Search in Rotated Sorted Array

    截图来源:code ganker博客


    Paste_Image.png

    时间复杂度为O(logn)

    81. Search in Rotated Sorted Array II

    截图来源:code ganker博客


    Paste_Image.png

    与上一题不同的地方在于这里允许出现重复数字,对边缘进行移动,值到相遇或者边缘的值与mid值不相等:
    while left<mid and nums[left]==nums[mid]: left += 1
    时间复杂度在最坏情况下变为O(n)

    34. Search for a Range

    • 循环条件为while left <= right:, 要包含等于,因为可能存在数组里只有1到2个数字这种情况
    • 当找到target后,即nums[mid] == target: 此时将mid赋值给两个新的指针,lpivot, rpivot,从mid出发分别朝左右前进,如果
      lpivot >0 and nums[lpivot] == target
      rpivot < len(nums) and nums[rpivot] == target
      就继续向左右移动这两个指针,最后返回[lpivot, rpivot]

    35. Search Insert Position

    循环条件中依然包含等于,原因和上一道题一样。
    最后如果target不存在,返回r+1就可以了

    50. Pow(x, n)

    计算x的n次方。
    分几种情况:n==0, n==1, n<0, n%2==0
    当n<0时,if n<0: n = -n, x = 1/x,对n, x做相应的变化
    if n%2 == 0: return self.myPow(x*x, n/2)
    else: return x*self.myPow(x*x, n/2)
    因为每次n都变为原来的二分之一,所以总运行时间为O(logn)

    69. Sqrt(x)

    对x进行二分法,l, r = 0, x
    从x的一半开始试:

    while l<= r:
             mid = (l+r)/2
             if mid*mid <= x < (mid+1)*(mid+1):
                       return mid
             elif mid*mid > x:
                       r = mid -1
             else:
                       l = mid +1
    

    if mid*mid <= x < (mid+1)*(mid+1): 这句判断的原因是,x有可能不能恰好被开平方,比如10,sqrt(10) = 3

    74. Search a 2D Matrix

    在一个有序的二维矩阵中找target, 因为这个二维矩阵是有序的,我们依然可以按照最普通的二分查找来做。
    m, n = len(matrix), len(matrix[0])
    l, r = 0, m*n-1

    while l <= r
         mid = (l+r)/2
         num = matrix[mid/n][mid%n]
         if num == target:
            return True
    

    最重要的地方就是如何只根据mid来找到在二维数组中对应的数字。 num = matrix[mid/n][mid%n], n是每一行的元素个数,mid除n可以得到所在的行数,对n取余可以得到所在的列数。
    *** if not matrix or target is None: return False
    这里不能写matrix is None, 当matrix为[ ]时,就不属于None

    153. Find Minimum in Rotated Sorted Array

    依然是在rotated array中找值,这次没有给target, 而是让找出最小值,在没有旋转之前,最小值就是第一个值,因为是有序序列。

    1. O(n)解法:用for循环遍历数组,找到第一个nums[i] > nums[i+1]时,返回nums[i+1], 若都不存在,则返回nums[0],此时证明序列是有序的并且没有被旋转。
    2. O(logn)解法:用二分查找来做。
    while left <= right:
             if nums[left] < nums[right]:
                return nums[left]
             else:
                mid = (left + right)/2
                if nums[mid] < nums[right]:
                   right = mid
                else:
                   left = mid + 1
    return nums[right]
    

    和其他地方不同的地方在于,这里更新right时不要对mid减1,因为nums[mid]可能就是那个最小的数。如果对right进行mid-1,就会把最小的数给错过。循环终止后返回nums[right]

    162. Find Peak Element

    peak element就是比左右邻居都大的数,这题默认nums[-1]=nums[n]= 负无穷,题目要求复杂度为log形式,所以依然要用二分法来做。

    while left < right:
           mid = (left+right)/2
           if nums[mid] > nums[mid+1]:
              right = mid
           else:
              left = mid+1
    return left
    

    比较nums[mid]和nums[mid+1],如果nums[mid]更大,就对right进行更新,将mid赋值给他。这里不需要mid-1, 因为mid这个元素,可能就是我们要找的peak元素,如果使right = mid-1,就有可能把这个元素给错过去。而left=mid+1是因为nums[mid+1]是那个更大的元素,将Left指向它,就不会错过。
    *还有一点需要注意,循环条件不能有等于。有等于的话会循环超时。
    *最后可以返回left也可以返回right,因为循环终止时,left=right

    209. Minimum Size Subarray Sum

    用Sliding window和two pointers可以得到O(n)解法:
    left, right均从0开始,维护一个sliding window, 不断累加sum, 当sum>=s时,更新minlen, 并且减去nums[left],将left向右移动一位,直到sum小于s。然后向右移动一位right,直到right到达数组边界为止。
    注意right<len(nums), 是没有等于的,因为要累加nums[right]的值,有等于的话就会数组越界。

    left, right, sum, minlen = 0, 0, 0, len(nums)+1
    while right < len(nums):
             sum += nums[right]
             while sum >= s:
                     minlen = min(minlen,  right - left +1)
                     sum -= nums[left]
                     left += 1
             right += 1
    
    if len(minlen)==len(nums)+1:
             return 0
    else:
            return minlen
    
    

    相关文章

      网友评论

          本文标题:Leetcode--Binary Search

          本文链接:https://www.haomeiwen.com/subject/daxagttx.html