정수 배열 nums 안에 target과 값이 같은 index를 반환하자. 만약 없다면 -1 반환
입력
출력
사실 정렬된 배열이 반으로 분할 후, 다시 붙인 배열을 탐색하는 거라, 반 반 따로 정렬이 되어 있으므로, 간단한 조건문 여러 개로 구현이 될거라 생각했다.
그래서 조건을 계속 쪼개기 시작했지만 조건은 너무 끝도 없어 이 방법이 아니라 생각했다.
class Solution {
public int search(int[] nums, int target) {
int start = 0, end = nums.length - 1;
int mid = (start + mid) / 2;
while (start <= end) {
if (nums[mid] == target)
return mid;
if (start <= end) {
if (nums[mid] < target) {
start = mid + 1;
}
else {
end = mid - 1;
}
}
else {
if (nums[mid] > nums[end]) {
if (target > nums[start])
end = mid - 1;
else
start = mid + 1;
}
else {
if (target > nums[end])
end = mid - 1;
else
start = mid + 1;
}
}
}
return -1;
}
}
일단, 다른 풀이의 핵심은 rotate 돌기 전의 오름차순으로 정렬되어 있던 배열의 첫 번째 요소가 현재 어디에 있는 지 먼저 찾고, target과 값이 같은 요소를 탐색한 후, 그걸 이용한다.
똑같이 binary search를 이용해, 가장 작은 값을 탐색하기 때문에, 두 번의 binary search가 실행되지만, 실행 시간은 O(logn)에서 바뀌지 않는다.
public int search(int[] nums, int target) {
int minIdx = findMinIdx(nums);
if (target == nums[minIdx]) return minIdx;
int m = nums.length;
int start = (target <= nums[m - 1]) ? minIdx : 0;
int end = (target > nums[m - 1]) ? minIdx : m - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (nums[mid] == target) return mid;
else if (target > nums[mid]) start = mid + 1;
else end = mid - 1;
}
return -1;
}
public int findMinIdx(int[] nums) {
int start = 0, end = nums.length - 1;
while (start < end) {
int mid = start + (end - start) / 2;
if (nums[mid] > nums[end]) start = mid + 1;
else end = mid;
}
return start;
}
한 번의 반복문으로 꼭 끝낼 필요는 없다는 걸 명심해야겠다. 사실 2logn 이나 logn이나 시간복잡도는 O(logn)이기 때문이다.