Java реализует LeetCode 34 для поиска первой и последней позиций элементов в отсортированном массиве (подробное решение)

34. Найдите первую и последнюю позицию элемента в отсортированном массиве.
Вам дан массив целых чисел nums, расположенных в неубывающем порядке, и целевое значение. Найдите начальную и конечную позицию данного целевого значения в массиве.

Если целевое значение target не существует в массиве, возвращается [-1, -1].

Для решения этой проблемы вам необходимо разработать и реализовать алгоритм с временной сложностью O(log n).

Пример 1:

Ввод: nums = [5,7,7,8,8,10], цель = 8
Вывод: [3,4]
Пример 2:

Ввод: nums = [5,7,7,8,8,10], цель = 6
Вывод: [-1,-1]
Пример 3:

Ввод: nums = [], цель = 0
Вывод: [-1,-1]

намекать:

0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums — неубывающий массив
-109 <= цель <= 109

Крайнее левое и крайнее правое решения двоичного поиска

class Solution {
    
    
    public int[] searchRange(int[] nums, int target) {
    
    
        int x = left(nums,target);
        if(x == -1){
    
    
            return new int[] {
    
    -1,-1};
        }else{
    
    
            return new int[] {
    
    x,right(nums,target)};
        }
    }

    public int left(int[] nums, int target){
    
    
        int i = 0,j = nums.length - 1;
        int candidate = -1;
        while(i <= j){
    
    
            int m = (i + j) >>> 1;
            if(target < nums[m]){
    
    
                j = m - 1;
            }else if(target > nums[m]){
    
    
                i = m + 1;
            }else{
    
    
                candidate = m;
                j = m - 1;
            }
        }
        return candidate;
    }

        public int right(int[] nums, int target){
    
    
        int i = 0,j = nums.length - 1;
        int candidate = -1;
        while(i <= j){
    
    
            int m = (i + j) >>> 1;
            if(target < nums[m]){
    
    
                j = m - 1;
            }else if(target > nums[m]){
    
    
                i = m + 1;
            }else{
    
    
                candidate = m;
                i = m + 1;
            }
        }
        return candidate;
    }
}
  • Сначала вызовите left метод, чтобы получить левую границу целевого значения x.
    Если левая граница равна -1, это означает, что целевое значение не существует в массиве и массив возвращается напрямую {-1, -1}.
    Если левая граница существует, вызовите rightметод, чтобы получить правую границу целевого значения, и x верните ее вместе с правой границей в целочисленный массив.
  • Определите leftметод, который принимает упорядоченный массив numsи целевое значение targetи возвращает левую границу целевого значения.
    Инициализируйте левый и правый указатели i, jчтобы они указывали на начало и конец массива соответственно.
    Инициализируйте значение-кандидат candidateкак -1, указывая, что левая граница целевого значения еще не найдена.
    Введите цикл до тех пор, пока левый указатель не станет больше правого:
    вычислите промежуточный индекс m, сложив левый и правый указатели и разделив 2.
    Если целевое значение меньше среднего элемента, обновите правый указатель jна m - 1.
    Если целевое значение больше среднего элемента, обновите левый указатель iна m + 1.
    Если целевое значение равно среднему элементу, mназначьте candidateи jобновите правый указатель m - 1, чтобы продолжить поиск левой границы.
    После завершения цикла возвращается значение-кандидат candidate.
  • Определите right метод, который принимает упорядоченный массив numsи целевое значение targetи возвращает правую границу целевого значения.
    Аналогично методу left , с небольшими изменениями. Когда целевое значение будет найдено, mприсвойте его candidate, i обновите левый указатель на m + 1и продолжайте поиск правой границы.
  • Наконец, левая и правая границы объединяются в целочисленный массив и возвращаются.

Guess you like

Origin blog.csdn.net/weixin_61370021/article/details/131536189