leetcode 744. Find 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
              """
              '''        
              Input:
      letters = ["c", "f", "j"]
      target = "j"
      Output: "c"
      
      Input:
      letters = ["c", "f", "j"]
      target = "k"
      Output: "c"
              just check the last letter if letters[-1] <= target: return letters[0]
              
              
              Input:
      letters = ["c", "f", "j"]
      target = "a"
      Output: "c"
              just check the first letter ....
      
      Input:
      letters = ["c", "f", "j"]
      target = "c"
      Output: "f"
      use binsearch mid letter > target and mid-letter <= target
      
      Input:
      letters = ["c", "f", "j"]
      target = "d"
      Output: "f"
      
      Input:
      letters = ["c", "f", "j"]
      target = "g"
      Output: "j"
              '''
              if letters[0] > target or letters[-1] <= target:
                  return letters[0]
              
              i = 0
              j = len(letters)-1
              while i <= j:
                  mid = (i+j) >> 1
                  if letters[mid] <= target:
                      i = mid + 1
                  else:
                      if letters[mid-1] <= target:
                          return letters[mid]
                      else:
                          j = mid -1                                        

      就是二分变种,没啥说的,但是要防止mid-1  < 0,因此,先判断了一下,确保target在letters里面。

    4. class Solution(object):
          def nextGreatestLetter(self, letters, target):
              """
              :type letters: List[str]
              :type target: str
              :rtype: str
              """
              length = len(letters)   
              if letters[0] > target or letters[-1] <= target:
                  return letters[0]
              i, j = 0, length-1
              while i <= j:
                  mid = (i+j) >> 1
                  if letters[mid] <= target:
                      i = mid + 1
                  else:
                      j = mid - 1                                
              return letters[i]
      

      本质,循环结束一定有,i=j+1, 在循环体里结束前一刻必然有,j==i==mid,走到判断那里,要么j=mid-1(满足target <letters[mid]),或者i=mid+1(letters[mid] <= target),所以一定有letters[j] <= target < letters[i]

    5. 补充:bisect_right,

      1. #在L中查找x,x存在时返回x右侧的位置,
      2. x不存在返回应该插入的位置..


    6. >>> import bisect
      >>> L = [1,3,3,6,8,12,15]
      >>> bisect.bisect_right(L,3)
      3
      >>> bisect.bisect_right(L,7)
      4
      >>> bisect.bisect_right(L,15)
      7
      >>> bisect.bisect_right(L,19)
      7
      >>> bisect.bisect_right(L,1)
      1
      >>> bisect.bisect_right(L,0)
      0
posted @ 2018-04-06 17:28  bonelee  阅读(165)  评论(0编辑  收藏  举报