每日一道算法Day19

91 阅读1分钟

题目描述:

image.png

大致思路:

题目要求时间复杂度为 O(log n), 其实就是提示使用二分法了。

代码如下:

function searchRange(nums: number[], target: number): number[] {
  const res: number[] = [];
  if (nums.length === 0 || nums[0] > target) return [-1, -1];

  // let i = 0;
  // let j = nums.length - 1;
  // while (i <= j) {
  //   const mid = Math.floor((i + j) / 2);
  //一开始处理相等情况的时候采用了这种方式, 但是后面想了想好像不满足时间复杂度了, 于是有了下面这种写法
  //   if (nums[mid] === target) {
  //     let a = mid;
  //     let b = mid;
  //     while (a >= 0) {
  //       if (nums[--a] !== target) {
  //         res.push(a + 1);
  //         break;
  //       }
  //     }
  //     while (b <= nums.length - 1) {
  //       if (nums[++b] !== target) {
  //         res.push(b - 1);
  //         break;
  //       }
  //     }
  //     return res;
  //   }

  //   if (nums[mid] > target) {
  //     j = mid - 1;
  //   } else if (nums[mid] < target) {
  //     i = mid + 1;
  //   }
  // }
  const find = (model: 'left' | 'right') => {
    let left = 0;
    let right = nums.length - 1;
    let result = -1;
    while (left <= right) {
      const mid = Math.floor((left + right) / 2);
      if (nums[mid] === target) {
        result = mid;
        if (model === 'left') {
        //找到相等值后二分左侧的数组继续寻找
          right = mid - 1;
        } else if (model === 'right') {
        //找到相等值后二分右侧的数组继续寻找
          left = mid + 1;
        }
      }
      //因为是有序数组, 比较中间值后判断去左侧还是右侧数组中继续寻找
      if (nums[mid] > target) {
        right = mid - 1;
      } else if (nums[mid] < target) {
        left = mid + 1;
      }
    }
    return result;
  };
  res[0] = find('left');
  res[1] = find('right');
  return res;
}