Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You must write an algorithm with O(log n)
runtime complexity.
nums
target
target
이 nums
안에 있다면, 해당 index를 반환target
이 nums
안에 없다면, 삽입해야 할 index를 반환해당 문제가 Binary Search가 어울리는 이유
기본 전략
Binary Search라고 해도 front
, behind
pointer를 이동시키는 것에는 주의를 해야한다.
문제점
nums
범위 안에 target
이 존재한다는 전제를 한다.target
이 nums
범위 밖에 있다면, front
, behind
를 통해서만 위치를 알 수 없다.Input: nums = [1,3,5,6], target = 7; Output: 4
를 통과하지 않는다.class Solution {
public int searchInsert(int[] nums, int target) {
int front = 0;
int behind = nums.length - 1;
while (front < behind - 1) {
int middle = (front + behind) / 2;
if (target < nums[middle]) {
behind = middle;
} else if (target > nums[middle]){
front = middle;
} else {
return middle;
}
}
return front + 1;
}
}
초안에서 계산된 결과에서 target
이 nums
범위 안에 있는지 확인하는 과정을 추가했다.
Complexity
class Solution {
public int searchInsert(int[] nums, int target) {
int front = 0;
int behind = nums.length - 1;
while (front < behind - 1) {
int middle = (front + behind) / 2;
if (target < nums[middle]) {
behind = middle;
} else if (target > nums[middle]){
front = middle;
} else {
return middle;
}
}
if (target > nums[behind]) {
return behind + 1;
} else if (target <= nums[front]) {
return front;
}
return front + 1;
}
}
리팩토링 포인트
수정 전략
front
, behind
가 모두 가리키도록 만들어 분기문을 줄였다.target
이 nums
의 가장 뒤에 오는 경우를 설명할 수 없어 초기에 예외 처리 형식으로 설정하였다.Complexity
class Solution {
public int searchInsert(int[] nums, int target) {
if (target > nums[nums.length - 1]) {
return nums.length;
}
int front = 0;
int behind = nums.length - 1;
while (front < behind) {
int middle = (front + behind) / 2;
int middleValue = nums[middle];
if (target > middleValue) {
front = middle + 1;
} else {
behind = middle;
}
}
return front;
}
}