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
и продолжайте поиск правой границы. - Наконец, левая и правая границы объединяются в целочисленный массив и возвращаются.