1. 程式人生 > 其它 >LeetCode題解:在排序陣列中查詢元素的第一個和最後一個位置

LeetCode題解:在排序陣列中查詢元素的第一個和最後一個位置

技術標籤:# 解題思想:二分法【演算法與資料結構】LeetCode資料結構演算法查詢第一個和最後一個位置javascript題解

在排序陣列中查詢元素的第一個和最後一個位置(middle)

一、題目

LeetCode 34.在排序陣列中查詢元素的第一個和最後一個位置

給定一個按照升序排列的整數陣列 nums,和一個目標值 target。找出給定目標值在陣列中的開始位置和結束位置,如果陣列中不存在目標值 target,返回 [-1, -1]。

你可以設計並實現時間複雜度為 O(log n) 的演算法解決此問題嗎?

示例 1:

輸入:nums = [5,7,7,8,8,10], target = 6
輸出:[-1,-1]

示例 2:

輸入:nums = [5,7,7,8,8,10], target = 8
輸出:[3,4]

提示:

  • nums 是一個非遞減陣列

二、基礎模版 III

因為我們的判斷區間最少為2個元素,所以我們要注意迴圈的執行條件

  1. 簡單的判斷邊界: nums.length === 0,return -1
  2. 定義初始的左右邊界:left = 0, right = nums.length - 1
  3. 確定執行條件:left + 1 < right,這也意味著查詢區間要存在 3 個元素;
  4. 向左查詢時:right = mid
  5. 向左查詢時:left = mid
  6. 判斷剩下的兩個元素哪個符合目標元素,並返回結果;

三、題解

分析模版

  • 我們的目標是:尋找目標值的起始下標和終止下標,但它是可能重複的
  • 針對這樣的情況,我們要將判斷拆解成查詢目標首次出現的位置,和最後一次出現的位置\
  • 我們講一個大問題,用拆分成2個小問題,並用二分但解決對應的問題
var searchRange = function(nums, target) {
    const NO_TARGET = [-1, -1];
    if (nums.length === 0) return NO_TARGET;
    // 判斷首次位置
    let firstPosition = findFirstPos(nums, target);
    if (
firstPosition < 0) return NO_TARGET; // 獲取最終出現位置 let lastPostion = findLastPos(nums, target); return [firstPosition, lastPostion]; }; // 首次出現目標位置,參考模板II const findFirstPos = function(nums, target) { let left = 0; let right = nums.length - 1; while (left < right) { let mid = left + ((right - left) >> 1); if (nums[mid] === target) { right = mid; // 捨棄右側,留mid,不管右側是否有重複值,我們只留1個滿足條件的 } else if (nums[mid] > target) { right = mid - 1; // 直接捨棄 } else { left = mid + 1; // 直接捨棄 } } if (nums[left] === target) return left; return -1; } // 首次出現目標位置,參考模板II const findLastPos = function(nums, target) { let left = 0; let right = nums.length - 1; while (left < right) { let mid = left + ((right - left + 1) >> 1); // 注意這裡 + 1是為了向上取整,因為我們要查詢最後出現的元素 if (nums[mid] === target) { left = mid; // 捨棄右側,留mid } else if (nums[mid] > target) { right = mid - 1; // 直接捨棄 } else { left = mid + 1; } } if (nums[left] === target) return left; return -1; }

四、寫在最後

本文是二分查詢-模版III 的第一題,後面的幾道題的也算是本模版的微調版,加油~

如果對你有所幫助不妨給本專案的github 點個 star,這是對我最大的鼓勵

關於我

  • 花名:餘光
  • WX:j565017805
  • 沉迷 JS,水平有限,虛心學習中

其他沉澱

````