尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

千问 LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置 JavaScript实现

千问    LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置 JavaScript实现 LeetCode 34 在排序数组中查找元素的第一个和最后一个位置的 JavaScript 实现核心思路是两次二分查找分别寻找目标元素的左边界和右边界。算法思路这道题考察的是二分查找的边界收缩寻找左边界当 nums[mid] target 时不立即返回而是收缩右边界right mid - 1继续向左半部分寻找。寻找右边界当 nums[mid] target 时收缩左边界left mid 1继续向右半部分寻找。注意由于我们在命中目标时继续收缩边界最终 left 和 right 会越界或指向非目标元素。因此最后需要判断 left 是否合法且对应元素是否真的等于 target。JavaScript 代码实现/**param {number[]} numsparam {number} targetreturn {number[]}*/var searchRange function(nums, target) {// 寻找左边界let left 0;let right nums.length - 1;while (left right) {let mid Math.floor(left (right - left) / 2); // 防止整数溢出if (nums[mid] target) {left mid 1;} else {// 当 nums[mid] target 时收缩右边界right mid - 1;}}// 循环结束时left 指向第一个等于 target 的位置let leftIdx left;// 寻找右边界left 0;right nums.length - 1;while (left right) {let mid Math.floor(left (right - left) / 2);if (nums[mid] target) {right mid - 1;} else {// 当 nums[mid] target 时收缩左边界left mid 1;}}// 循环结束时right 指向最后一个等于 target 的位置let rightIdx right;// 边界检查如果 leftIdx 越界或者对应元素不等于 target说明数组中不存在 targetif (leftIdx nums.length nums[leftIdx] target) {return [leftIdx, rightIdx];}return [-1, -1];};JavaScript 实现的关键细节防止整数溢出虽然 JavaScript 中的 Number 是双精度浮点数但在处理极大数组时left right 依然可能超出安全整数范围。使用 Math.floor(left (right - left) / 2) 是标准的防溢出写法。搜索区间 [left, right]这里使用了左闭右闭区间 [left, right]。初始时 right nums.length - 1。循环条件为 left right。这种写法与 Python 版本一致逻辑直观。为什么最后检查 leftIdx 而不是 rightIdx因为 leftIdx 是第一个 target 的位置。如果 target 不存在比如找 9leftIdx 可能会停在 10 的位置或者越界。只要 leftIdx 合法且 nums[leftIdx] target就一定能推导出 rightIdx 也是合法的。时间复杂度执行了两次独立的二分查找时间复杂度为 O(log n)空间复杂度为 O(1)。掌握这种“遇到目标值不返回而是继续收缩边界”的二分思想可以秒杀所有求边界的二分题如 LeetCode 278 第一个错误的版本、LeetCode 35 搜索插入位置等。需要我帮你把这道题的合并写法单函数实现通过传入布尔值决定收缩哪一边也写出来吗面试时写单函数会显得更精炼。
返回列表