Leetcode 刷题 Binary Search Easy难度经验总结

来源:互联网 发布:如何防止网络麻将开挂 编辑:程序博客网 时间:2024/06/18 14:46

刷了4道Binary Search  Easy难度的题

二叉搜索思想好想,难在边界的控制上,于是乎我就在思考能不能背下一个定式,遇到二分搜索的题目就套这个定式。

我做的第一道二叉搜索的题目就是一个很好的定式:

744Find Smallest Letter Greater Than Target

Given a list of sorted characters letters containing only lowercase letters, and given a target letter target, find the smallest element in the list that is larger than the given target.

Letters also wrap around. For example, if the target is target = 'z' and letters = ['a', 'b'], the answer is 'a'.

Examples:

Input:letters = ["c", "f", "j"]target = "a"Output: "c"Input:letters = ["c", "f", "j"]target = "c"Output: "f"Input:letters = ["c", "f", "j"]target = "d"Output: "f"Input:letters = ["c", "f", "j"]target = "g"Output: "j"Input:letters = ["c", "f", "j"]target = "j"Output: "c"Input:letters = ["c", "f", "j"]target = "k"Output: "c"

Note:

  1. letters has a length in range [2, 10000].
  2. letters consists of lowercase letters, and contains at least 2 unique letters.
  3. target is a lowercase letter.
class Solution(object):    def nextGreatestLetter(self, letters, target):        """        :type letters: List[str]        :type target: str        :rtype: str        """        low = 0        high = len(letters)        while (low < high) :            mid = low + (high - low) / 2            if (letters[mid] <= target):                 low = mid + 1            else: high = mid                return letters[low % len(letters)]
这里面的low,high都是指脚标
这个定式的特点是:
给定一个有序排列(可能有重复值,可能没有)的数组,和一个target

low的初始值指向第一个元素 ,本意是指脚标
high的初始值指向最后一个元素还往后移一个,本意是指脚标
 while(low<high):
       mid的公式恒久不变 mid= low +int((high -low)/2)       
       if (mid<=target):
              low=mid+1
      else: 
            high=mid
  return low 

return的时候,low和high必相等,但不一定等于mid
返回的low指向比target大的数中最小的那个数!(这个性质很好)


现在我们试试套用这个定式再做一道题:

34Search for a Range

Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

class Solution(object):    def searchRange(self, nums, target):        """        :type nums: List[int]        :type target: int        :rtype: List[int]        """                if len(nums)==0:#空输入处理            return [-1,-1]              low = 0        high = len(nums)        while (low < high):            mid = low + int((high - low) / 2)            if (nums[mid] <= target):                low = mid + 1            else:                high = mid        start=low-1#target所在的位置,因为low是比target大的数中最小的一个        end=low-1#target所在的位置,因为low是比target大的数中最小的一个        if (nums[end] != target ):#target不存在于数组中            return [-1,-1]        else:#target存在于数组中            while (start != 0 and nums[start] == nums[start - 1]):#看看start左边是不是还有一样的值                start = start - 1            return [start,end]
完美地套用了我们的定式,

最后的if -else分支是根据本题再做的逻辑补充


374.Guess Number Higher or Lower

We are playing the Guess Game. The game is as follows:

I pick a number from 1 to n. You have to guess which number I picked.

Every time you guess wrong, I'll tell you whether the number is higher or lower.

You call a pre-defined API guess(int num) which returns 3 possible results (-11, or 0):

-1 : My number is lower 1 : My number is higher 0 : Congrats! You got it!

Example:

n = 10, I pick 6.Return 6.

# The guess API is already defined for you.# @param num, your guess# @return -1 if my number is lower, 1 if my number is higher, otherwise return 0# def guess(num):class Solution(object):    def guessNumber(self, n):        """        :type n: int        :rtype: int        """        low=1#Low index        high=n+1#high index        while (low<high):            mid=low+int((high-low)/2)            if (guess(mid)==1):#mid<=target                   low=mid+1            elif(guess(mid)==-1):                   high =mid             elif(guess(mid)==0):                return mid                                             

排序的数组不是nums参数的形式,而是给了一个参数n,对应数组1,2,....n

low在这里面还指向有序数组里最小的那个第一个数

high在这里还是指向 数组最后一个数还往后移一位

仍然符合定式


278First Bad Version

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.

You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

# The isBadVersion API is already defined for you.# @param version, an integer# @return a bool# def isBadVersion(version):class Solution(object):    def firstBadVersion(self, n):        """        :type n: int        :rtype: int        """        low=1#low_index        high=n+1#high_index        while(low<high):            mid=low+int((high-low)/2)            if(isBadVersion(mid)==True):                    high=mid            else:                    low=mid+1                    return low                                     

因为现在比如对于 1, 2, 3这个数组

脚标low =1,high=4                                        类比可得应该return low 

并不是实际上的 low_index=0 ,high_index=3  return low-1

依然是定式的变形 


总结:

记住定式的套路(<= ,等啊不等啊什么的)

依据题意和实际情况改一下low,high的初始值

和return的值


这个套路目前为止没失败过


阅读全文
0 0
原创粉丝点击