本文最后更新于:2023年3月19日 晚上
                
              
            
            
              L34. 在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
1 2
   | 输入: nums = , target = 8 输出: 
 
  | 
 
示例  2:
1 2
   | 输入: nums = , target = 6 输出: 
 
  | 
 
思路
二分搜索,首先用二分法查出第一个和 target 相等的元素的下标。如果 index 仍然等于-1 则不存在该元素,返回[-1,-1]。
分别从该元素的左边和右边查到开始和结尾,看 target 元素出现的第一次和最后一次。有以下逻辑:
第一次二分查找左半边,查找第一个 target 元素,设置左右指针分别为 l 和 index。
- 如果最左边的元素即 l 指向的元素就为 target,将 first 设为 l
 
- 计算 middle,如果 middle 等于 target,令 r–,继续判断右边下一个是否和 target 相等
 
- 如果 middle 指向的数小于目标值,令 l=middle+1,继续二分查找
 
第二次二分查找右半边,查最后一个 target 元素,逻辑类似。
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
   | 
 
 
 
  var searchRange = function (nums, target) {   let l = 0,     r = nums.length - 1,     index = -1;   while (l <= r) {     let middle = parseInt((l + r) / 2);     if (nums[middle] === target) {       index = middle;       break;     } else if (nums[middle] < target) l = middle + 1;     else r = middle - 1;   }
    if (index === -1) return [-1, -1];   let first = -1,     last = -1;   (l = 0), (r = index);   while (l <= r) {     let middle = parseInt((l + r) / 2);     if (nums[middle] === target) {       if (l === 0 && nums[l] === target) {         first = l;         break;       } else if (middle > 0 && nums[middle - 1] !== target) {         first = middle;         break;       }       r--;     } else if (nums[middle] < target) l = middle + 1;   }   (l = index), (r = nums.length - 1);   while (l <= r) {     let middle = parseInt((l + r) / 2);     if (nums[middle] === target) {       if (r === nums.length - 1 && nums[r] === target) {         last = r;         break;       } else if (middle < nums.length - 1 && nums[middle + 1] !== target) {         last = middle;         break;       }       l++;     } else if (nums[middle] > target) r = middle - 1;   }   return [first, last]; };
 
  |