LeetCode #744 寻找比目标字母大的最小字母 二分查找

LeetCode #744 寻找比目标字母大的最小字母

题目描述

给定一个只包含小写字母的有序数组 letters 和一个目标字母 target,寻找有序数组里面比目标字母大的最小字母。

在比较时,数组里字母的是循环有序的。举个例子:

  • 如果目标字母 target = 'z' 并且有序数组为 letters = ['a', 'b'],则答案返回 'a'
  • 如果目标字母 target = 'n' 并且有序数组为 letters = ['m', 'z', 'c', 'f', 'j'] ,则答案返回 'z' 感觉是误导人的,看别人的解法二分查找都无法解决这种,意思就是说输入进去的数组顺序还是 ['c', 'f', 'j', 'm', 'z']

示例:

输入:
letters = ["c", "f", "j"]
target = "a"
输出: "c"

输入:
letters = ["c", "f", "j"]
target = "c"
输出: "f"

输入:
letters = ["c", "f", "j"]
target = "d"
输出: "f"

输入:
letters = ["c", "f", "j"]
target = "g"
输出: "j"

输入:
letters = ["c", "f", "j"]
target = "j"
输出: "c"

输入:
letters = ["c", "f", "j"]
target = "k"
输出: "c"

提示:

  1. letters长度范围在[2, 10000]区间内。
  2. letters 仅由小写字母组成,最少包含两个不同的字母。
  3. 目标字母target 是一个小写字母。
思路分析

二分查找难的是边界条件的判断:

  1. letters[m] < target 时,需要往右边查找,l = m + 1
  2. letters[m] = target 时,需要往右边查找,l = m + 1
  3. letters[m] > target 时,可以分两种情况
    • letters[m-1] <= target,说明 letters[m] 就是要找的字符,返回即可
    • 否则需要在左边继续查找,h = m -1
    • 也可以不做判断,最后输出,一直往左边找,直到 l > h 退出,这种情况退出的循环说明 l 就是要找的,其他情况退出的循环 l 会大于 n
class Solution:
    def nextGreatestLetter(self, letters: List[str], target: str) -> str:
        n = len(letters) 
        l = 0; h = n - 1
        while l <= h:
            m = l + (h - l) // 2
            if letters[m] <= target:
                l = m + 1
            else:
                h = m - 1
       	# 当l>n的时候说明没有找到,返回第一个
        return letters[l] if l < n else letters[0]
  • 时间复杂度: O ( l o g N ) O(logN) O(logN)
  • 空间复杂度: O ( 1 ) O(1) O(1)

你可能感兴趣的:(LeetCode,#,二分查找,数据结构,算法,leetcode,二分法)