34、在排序陣列中查詢元素的第一個和最後一個位置 | 演算法(leetode,附思維導圖 + 全部解法)300題

碼農三少發表於2021-12-11

零 標題:演算法(leetode,附思維導圖 + 全部解法)300題之(34)在排序陣列中查詢元素的第一個和最後一個位置

一 題目描述

題目描述
題目描述

二 解法總覽(思維導圖)

思維導圖

三 全部解法

1 方案1

1)程式碼:

// 方案1 “無視要求,直接呼叫 indexOf、 lastIndexOf”
var searchRange = function(nums, target) {
    return [nums.indexOf(target), nums.lastIndexOf(target)];
};

2 方案2

1)程式碼:

// 方案2 “普通版的雙指標”。

// 思路:
// 1)狀態初始化
// 2.1)通過移動left,找到 left 的值
// 2.2)通過移動right,找到 right 的值
// 3)根據目前的 left、right 值返回不同的結果
var searchRange = function(nums, target) {
    // 1)狀態初始化
    const l = nums.length;
    let left = 0,
        right = l - 1;
    
    // 2.1)通過移動left,找到 left 的值
    while (left < l) {
        if (nums[left] === target) {
            break;
        }
        else if (nums[left] > target) {
            left = -1;
            break;
        }
        else {
            left++;
        }
    }

    // 2.2)通過移動right,找到 right 的值
    while (right >= 0) {
        if (nums[right] === target) {
            break;
        }
        else if (nums[right] < target) {
            right = -1;
            break;
        }
        else {
            right--;
        }
    }

    // 3)根據目前的 left、right 值返回不同的結果。
    // 其實下面 4行 等同於
    // return left === l ? [-1, -1] : [left, right];
    if ([-1, l].includes(left) || [-1, -1].includes(left)) {
        return [-1, -1];
    }
    return [left, right];
}

3 方案3

1)程式碼:

// 方案3 “二分查詢”

// 參考:
// 1)https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/zai-pai-xu-shu-zu-zhong-cha-zhao-yuan-su-de-di-3-4/
const binarySearch = (nums, target, lower) => {
    let left = 0, right = nums.length - 1, ans = nums.length;
    while (left <= right) {
        const mid = Math.floor((left + right) / 2);
        if (nums[mid] > target || (lower && nums[mid] >= target)) {
            right = mid - 1;
            ans = mid;
        } else {
            left = mid + 1;
        }
    }
    return ans;
}

var searchRange = function(nums, target) {
    const leftIdx = binarySearch(nums, target, true);
    const rightIdx = binarySearch(nums, target, false) - 1;
    let ans = [-1, -1];

    if (leftIdx <= rightIdx && rightIdx < nums.length && nums[leftIdx] === target && nums[rightIdx] === target) {
        ans = [leftIdx, rightIdx];
    }
    
    return ans;
};

相關文章