중복된 값이 있는 정렬된 배열이 있을때, target값이 존재하는 범위를 리턴하라. 없다면 [-1,-1]을 리턴.
단, 시간복잡도는 O(log N)을 초과할 수 없다.
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Leetcode 에서 200
번째로 해결한 문제이다. 딱 두달전 5/9에 100개를 돌파했는데, 속도가 붙어서 어느덧 오늘 7/9이다. 두 달동안 100문제를 풀었다. 대견한 나를 칭찬해주기!
우선 binary search로 target값의 idx하나를 구한뒤, 그 idx로부터 좌/우로 동일한 값을 확장하며 범위를 구하는 방법. 평균적으로 O(logN) 이겠지만 최악의 경우 O(N)이 된다(모든 값이 동일한 경우).
순수하게 O(logN)으로만 해결할 수 있는 방법이 있을까?
int binary_search(int *nums, int left, int right, int target)
{
int mid = 0;
while (left <= right) {
mid = (left + right) / 2;
if (target == nums[mid])
return mid;
else if (target < nums[mid])
right = mid - 1;
else if (nums[mid] < target)
left = mid + 1;
}
return -1;
}
int* searchRange(int* nums, int numsSize, int target, int* returnSize){
int *ret = (int *)malloc(sizeof(int) * 2);
*returnSize = 2;
int t_idx = 0;
int l_idx = 0, r_idx = 0;
t_idx = binary_search(nums, 0, numsSize -1, target);
l_idx = t_idx;
r_idx = t_idx;
if (t_idx != -1) {
while (l_idx - 1 >= 0 && nums[l_idx - 1] == nums[t_idx])
l_idx--;
while (r_idx + 1 <= numsSize -1 && nums[r_idx + 1] == nums[t_idx])
r_idx++;
}
ret[0] = l_idx;
ret[1] = r_idx;
return ret;
}
220725에 다시 풀어본 방식. binary search로 index를 찾은뒤 중간에서 좌우로 이동하며 같은값이 있는지 찾기. 항상 배열에서 two pointer 를 찾는 것을 어려워함. 두가지 경우로 방법을 정리해보자면
while (l_idx >= 0 && nums[l_idx] == target)
l_idx--;
while (r_idx < numsSize && nums[r_idx] == target)
r_idx++;
int* searchRange(int* nums, int numsSize, int target, int* returnSize){
*returnSize = 2;
int *ret = (int *)malloc(sizeof(int) * 2);
int idx = binary_search(nums, 0, numsSize - 1, target);
if (idx == -1) {
ret[0] = -1;
ret[1] = -1;
return ret;
}
int l_idx = idx, r_idx = idx;
while (l_idx >= 0 && nums[l_idx] == target)
l_idx--;
while (r_idx < numsSize && nums[r_idx] == target)
r_idx++;
ret[0] = l_idx + 1;
ret[1] = r_idx - 1;
return ret;
}