题目

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

数组里字母的顺序是循环的。举个例子,如果目标字母 target = z 并且有序数组为 letters = ['a', 'b'],则答案返回 a

示例:

  1. 输入:
  2. letters = ["c", "f", "j"]
  3. target = "a"
  4. 输出: "c"
  5. 输入:
  6. letters = ["c", "f", "j"]
  7. target = "c"
  8. 输出: "f"
  9. 输入:
  10. letters = ["c", "f", "j"]
  11. target = "d"
  12. 输出: "f"
  13. 输入:
  14. letters = ["c", "f", "j"]
  15. target = "g"
  16. 输出: "j"
  17. 输入:
  18. letters = ["c", "f", "j"]
  19. target = "j"
  20. 输出: "c"
  21. 输入:
  22. letters = ["c", "f", "j"]
  23. target = "k"
  24. 输出: "c"

注:

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

方案一(二分查找,模板三)

func nextGreatestLetter(letters []byte, target byte) byte {
    // 特殊情况处理
    if target < letters[0] || target >= letters[len(letters)-1] {
        return letters[0]
    }

    // 二分查找
    var left, right = 0, len(letters) - 1
    for left + 1 < right {
        var mid = (left + right) / 2
        // if letters[mid] == target {
        //        return letters[mid+1]
        // } else 
        if letters[mid] > target && letters[mid - 1] < target {
            return letters[mid]
        } else if letters[mid] > target {
            right = mid
        } else {
            left = mid
        }
    }

    // 尾处理: 结束条件 left + 1 == right
    var index int
    if letters[right] > target {
        index = right
    }
    if letters[left] > target {
        index = left
    }

    return letters[index]
}
  • 注意上述代码中注释掉的部分,这样的判断是错误的, eg. ["e", "e", "e", "e", "e", "e", "n", "n", "n", "n"]

原文

https://leetcode-cn.com/explore/learn/card/binary-search/213/conclusion/852/