返回

在排列数组中查找元素的起始位置:LeetCode 34题精解

前端

深入剖析 LeetCode 34题

LeetCode第34题要求我们在一个按照升序排列的整数数组中查找给定目标值target的起始位置和结束位置。如果数组中不存在目标值,则返回[-1, -1]。

此题看似简单,却暗藏玄机,旨在考查算法设计和实现能力。

算法设计与实现

算法的关键在于充分利用数组已升序排列的特性,采用二分查找法,在数组中快速定位目标元素。具体步骤如下:

  1. 初始化左边界left为0,右边界right为数组长度n-1。
  2. 计算数组中间位置mid=(left+right)/2。
  3. 比较nums[mid]和target的值:
    • 如果nums[mid]等于target,则更新起始位置start为mid,并继续向右搜索,以找到结束位置end。
    • 如果nums[mid]大于target,则将right更新为mid-1,继续向左搜索。
    • 如果nums[mid]小于target,则将left更新为mid+1,继续向右搜索。
  4. 重复步骤2和3,直到left大于right,此时表示未找到目标元素,返回[-1, -1]。

实现示例(JavaScript)

/**
 * 在排列数组中查找元素的起始位置和结束位置
 * @param {number[]} nums 排序数组
 * @param {number} target 目标值
 * @returns {[number, number]} 返回起始位置和结束位置,如果不存在目标元素,则返回[-1, -1]
 */
const searchRange = (nums, target) => {
  let left = 0, right = nums.length - 1;
  let start = -1, end = -1;

  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (nums[mid] === target) {
      start = mid;
      end = mid;
      // 向左搜索起始位置
      while (mid > 0 && nums[mid - 1] === target) {
        mid--;
        start = mid;
      }
      // 向右搜索结束位置
      while (mid < nums.length - 1 && nums[mid + 1] === target) {
        mid++;
        end = mid;
      }
      break;
    } else if (nums[mid] < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }
  }

  return [start, end];
};

总结

通过对LeetCode第34题的深入剖析和算法实现,我们掌握了二分查找法在查找有序数组中的元素时的强大威力。同时,也体会到算法设计和实现过程中的严谨性和创造性。