1. /**
    2. * leetcode #34 在排序数组中查找元素的第一个和最后一个位置
    3. * https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
    4. *
    5. * 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
    6. * 你的算法时间复杂度必须是 O(log n) 级别。
    7. * 如果数组中不存在目标值,返回 [-1, -1]
    8. *
    9. * 输入: nums = [5,7,7,8,8,10], target = 8
    10. * 输出: [3,4]
    11. *
    12. * 输入: nums = [5,7,7,8,8,10], target = 6
    13. * 输出: [-1,-1]
    14. * **/
    15. // 由于数组已经排序,因此整个数组是单调递增的,我们可以利用二分法来加速查找的过程。
    16. // 考虑target 开始和结束位置,
    17. // 其实我们要找的就是数组中「第一个等于target 的位置」(记为 leftIdx)
    18. // 和「第一个大于target 的位置减一」(记为 rightIdx)。
    19. // 二分查找中,寻找 leftIdx 即为在数组中寻找第一个大于等于 target 的下标,
    20. // 寻找 rightIdx 即为在数组中寻找第一个大于 target
    21. // binarySearch(nums, target, lower) 表示在 nums 数组中二分查找 target 的位置,如果 lower 为true,
    22. // 则查找第一个大于等于 target 的下标,否则查找第一个大于 target 的下标。
    23. // 最后,因为 target 可能不存在数组中,
    24. // 因此我们需要重新校验我们得到的两个下标 leftIdx 和 rightIdx,
    25. // 看是否符合条件,如果符合条件就返回 [leftIdx,rightIdx],不符合就返回 [−1,−1]。
    26. function searchRange(nums, target) {
    27. let res = [-1, -1];
    28. const leftIndex = binarySearch(nums, target, true);
    29. const rightIndex = binarySearch(nums, target, false) - 1;
    30. if (leftIndex <= rightIndex && rightIndex < nums.length && nums[leftIndex] == target && nums[rightIndex] == target) {
    31. res = [leftIndex, rightIndex]
    32. }
    33. return res
    34. };
    35. function binarySearch(nums, target, lower) {
    36. let left = 0,
    37. right = nums.length - 1,
    38. ans = nums.length;
    39. while (left <= right) {
    40. const m = Math.floor((left + right) / 2)
    41. if (nums[m] > target || (lower && nums[m] >= target)) {
    42. right = m - 1
    43. ans = m
    44. } else {
    45. left = m + 1
    46. }
    47. }
    48. return ans
    49. }