LeetCode에 있는 study plan 중 Algorithm 1을 풀어보겠습니다.
첫 주제는 이분 탐색(Binary Search) 입니다.
이분 탐색을 간단하게 설명하자면, 정렬된 배열에서 특정한 숫자를 효율적으로 찾는 방법입니다.
[1, 2, 3, 4, 5, 6] 배열에서 4의 위치를 찾고 싶다 할 때, 가장 먼저 드는 생각은 맨처음부터 하나하나 찾아 나가는 것이죠.
이러면 O(n) 타임이 걸릴겁니다. 하지만 만약 배열의 길이가 무진장 길면?! O(n) 으로 해결이 안되는 경우가 생길 수도 있겠죠. 이럴 때 이분 탐색을 사용하면 O(log n) 타임으로 해결할 수 있습니다.
암튼.. 하루에 2~3 문제씩 있던데 이번엔 이분 탐색 세문제를 풀었습니다.
근데 뭐 너무너무너무 간단한 문제들이라.. 빠르게 정리해보겠습니다.
첫 문제입니다.
이름부터 binary search 네요. 정말 말 그대로 이분 탐색을 이용해서 target의 위치를 구하면 됩니다.
class Solution {
public int search(int[] nums, int target) {
return binarySearch(0, nums.length - 1, nums, target);
}
public int binarySearch(int start, int end, int[] nums, int target) {
if (start > end) return -1; // 종료 조건
int mid = (start + end) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) {
return binarySearch(mid + 1, end, nums, target); // target이 큰 경우 오른쪽 탐색
}
else {
return binarySearch(start, mid - 1, nums, target); // target이 작은 경우 왼쪽 탐색
}
}
}
아주아주 간단합니다.
두 번째 문제는 약~~~간 응용 문젭니다. 하지만 얘도 뭐 간단합니다. [1, 2, 3, ..., n] 의 버전이 있고, 그 중 k 번째 버전이 오류가 있으면 그 뒤에 있는 버전들도 오류가 있다... 그래서 첫번째 오류나는 k번째 버전을 찾아라.. 뭐 그런 문제입니다.
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */
public class Solution extends VersionControl {
public int firstBadVersion(int n) {
return binarySearch(1, n);
}
public int binarySearch(int start, int end) {
if (start >= end) return start;
int mid = start / 2 + end / 2;
if (!isBadVersion(mid)) {
return binarySearch(mid + 1, end);
} else return binarySearch(start, mid);
}
}
먼저 isBadVersion() 메서드를 써먹을 수 있는데, 얘가 나쁜 버전인지 여부를 반환해줍니다. 그럼 이분 탐색 메서드에서 다음 재귀함수가 탐색할 왼/오른쪽 부분을 정할 때 얘를 써먹으면 되겠죠. mid 변수가 나쁜 버전이 아니라면 그 이상의 버전이 나쁜 버전일테니 오른쪽을 탐색해줍니다.
반대로 나쁜 버전이라면? 앞쪽을 봐야겠죠. 근데 우연찮게 mid 번째 버전이 나쁜 버전 중 가장 낮은 버전일 수도 있습니다. 고로 앞쪽 범위에는 mid 도 꼭 포함시켜주어야 합니다.
아 참고로 인풋이 int 범위와 동일하기 때문에 mid 변수에 (start + end) / 2 를 해버리면 터져버릴지도...^^
세번째 문제입니다. 첫 문제랑 또오옥같은데 단 하나 다른게 만약 target이 nums 배열에 없다면 들어갈 위치를 리턴해주면 됩니다.
class Solution {
public int searchInsert(int[] nums, int target) {
return binarySearch(0, nums.length - 1, nums, target);
}
public int binarySearch(int start, int end, int[] nums, int target) {
if (start > end) return start; // 다른 부분
int mid = (start + end) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) return binarySearch(mid + 1, end, nums, target);
else return binarySearch(start, mid - 1, nums, target);
}
}
첫 문제와 다른 부분이 종료 조건밖에 없습니다.
당연합니다. 첫 문제에서 target을 찾지 못했을 경우 -1을 리턴하는데, 이 문제에서는 target이 들어갈 위치를 리턴하면 되기 때문이죠.
Day 2는 Two Pointers 입니다. 영어로 쓰니깐 멋있네요.
그럼 20000~
'Algorithm > LeetCode' 카테고리의 다른 글
[배열/시뮬레이션] 59. Spiral Matrix II (0) | 2023.05.10 |
---|---|
[배열/시뮬레이션] 54. Spiral Matrix (0) | 2023.05.10 |
[DP] 64. Minimum Path Sum - Java (0) | 2023.03.27 |
[투 포인터] 905. Sort Array By Parity - Java (0) | 2022.05.19 |
[투 포인터] Day 2. Two Pointers (0) | 2021.11.26 |