劍指leetcode—在排序數組中查找元素的第一個和最後一個位置

題目描述:給定一個按照升序排列的整數數組 nums,和一個目標值 target。找出給定目標值在數組中的開始位置和結束位置。

你的算法時間複雜度必須是 O(log n) 級別。
如果數組中不存在目標值,返回 [-1, -1]。

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

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

方法一:

線性掃描法

首先,我們對 nums 數組從左到右做線性遍歷,當遇到 target 時中止。如果我們沒有中止過,那麼 target 不存在,我們可以返回“錯誤代碼” [-1, -1] 。如果我們找到了有效的左端點座標,我們可以坐第二遍線性掃描,但這次從右往左進行。這一次,第一個遇到的 target 將是最右邊的一個(因爲最左邊的一個存在,所以一定會有一個最右邊的 target)。我們接下來只需要返回這兩個座標。

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] targetRange = {-1, -1};
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == target) {
                targetRange[0] = i;
                break;
            }
        }
        if (targetRange[0] == -1) {
            return targetRange;
        }
        for (int j = nums.length-1; j >= 0; j--) {
            if (nums[j] == target) {
                targetRange[1] = j;
                break;
            }
        }
        return targetRange;
    }
}

方法二:

二分查找法

算法工作過程與線性掃描方法類似,除了找最左和最右下標的方法。這裏我們僅僅做幾個微小的調整,用這種修改過的二分查找方法去搜索這個排過序的數組。首先,爲了找到最左邊(或者最右邊)包含 target 的下標(而不是找到的話就返回 true ),所以算法在我們找到一個 target 後不能馬上停止。我們需要繼續搜索,直到 lo == hi 且它們在某個 target 值處下標相同。
另一個改變是 left 參數的引入,它是一個 boolean 類型的變量,指示我們在遇到 target == nums[mid] 時應該做什麼。如果 left 爲 true ,那麼我們遞歸查詢左區間,否則遞歸右區間。考慮如果我們在下標爲 i 處遇到了 target ,最左邊的 target 一定不會出現在下標大於 i 的位置,所以我們永遠不需要考慮右子區間。當求最右下標時,道理同樣適用。

class Solution{
 private int extremeInsertionIndex(int [] nums,int target,boolean left)
  {
 int lo=0;
 int hi=nums.length; 
 while(lo<hi)
 {
  int mid=(lo+hi)/2;
  if(nums[mid]>target||(left&&target==nums[mid]))
 {
  hi=mid;
  }
  else
 {
  lo=mid+1;
  }
 } 
 return lo;
 } 
 public int [] searchRange(int [] nums,int target)
  {
 int [] targetRange={-1,-1};
 int leftIdx=extremeInsertionIndex(nums,target,true);
 if(leftIdx==nums.length||nums[leftIdx]!=target)
 return targetRange;
 targetRange[0]=leftIdx;
 targetRange[1]=extremeInsertionIndex(nums,target,false)-1;
 return targetRange;
 }
}

以上的算法使用c語言都很容易實現

對於二分查找法,很多人可能遇到過很多問題,比較mid的邊界問題,本博主在看了這篇二分查找算法細節詳解之後,大有感悟。所以推薦推薦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章