정리가 안된 책장에서 원하는 책을 찾는 방법은? 사람마다 다르겠지만 어느 방향이든 처음부터 순차적으로 찾을 수 있습니다.

상대방의 나이를 맞추고 싶다면? Up&Down 게임으로 예상 나이를 말하고 더 큰지 작은지 판단하여 절반씩 줄여나가는 전략을 사용합니다.


위 배열에서 45를 찾으려면 어떻게 해야 할까요?
배열로 구현하는 방법은 중간에 요소를 추가하거나, 삭제할 떄, 선형시간의 단점을 여전히 들고 있습니다.
그래서 이 방법을 해결하기 위해 이진 탐색 트리를 활용하 수 있습니다.


별다른 처리없이 부모 정점과 연결을 끊으면 된다.

제거되는 정점의 부모 간선을 자식 정점을 가르키게 바꾸면 된다.


만약 코딩테스트에서 이진 탐색을 사용한다면, 배열을 이용해 구현하는 것을 추천합니다.
const array = [1, 1, 5, 124, 400, 599, 1004, 2876, 8712];
function binarySearch(array, findValue) {
let left = 0;
let right = array.length - 1;
let mid = Math.floor((left + right) / 2);
// mid가 찾는 값이 일치할 떄까지 순회
while (left < right) {
if (array[mid] === findValue) {
return mid;
}
if (array[mid] < findValue) {
left = mid + 1;
} else {
right = mid - 1;
}
mid = Math.floor((left + right) / 2);
}
// 만약 left값과 right값이 동일할 경우 루프 탈출
// 루프를 그대로 빠져나온다면,
// 요소를 찾지 못했다는 뜻이기에 - 1반환
return -1;
}
console.log(binarySearch(array, 2876)); // 7
console.log(binarySearch(array, 1)); // 0
console.log(binarySearch(array, 500)); // -1
기존 이진 트리에 탐색 함수를 추가하면 됩니다.
class Node {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
class BinarySearchTree {
constructor() {
this.root = null;
}
// 이진 탐색 트리 요소 추가
insert(value) {
const newNode = new Node(value); // 노드를 하나 생성
// 루트가 비어있으면 생성한 노드가 루특가 됨
if (this.root === null) {
this.root = newNode;
return;
}
let currentNode = this.root;
// 현재 노드가 null이 아닐 떄까지 순회
while (currentNode !== null) {
// 만약 오른쪽 노드의 값보다 추가될 노드의 값이 큰 경우 오른쪽 노드에 삽입
if (currentNode.value < value) {
if (currentNode.right === null) {
currentNode.right = newNode;
break;
}
currentNode = currentNode.right; // null이 아닌 경우 이동만 함
} else {
// 만약 왼쪽 노드의 값보다 추가될 노드의 값이 큰 경우 왼쪽 노드에 삽입
if (currentNode.left === null) {
currentNode.left = newNode;
break;
}
currentNode = currentNode.left; // null이 아닌 경우 이동만 함
}
}
}
has(value) {
let currentNode = this.root;
while (currentNode !== null) {
if (currentNode.value === value) {
return true;
}
if (currentNode.value < value) {
currentNode = currentNode.right;
} else {
currentNode = currentNode.left;
}
}
return false;
}
}
const tree = new BinarySearchTree();
tree.insert(5);
tree.insert(4);
tree.insert(7);
tree.insert(8);
tree.insert(5);
tree.insert(6);
tree.insert(2);
console.log(tree.has(8)); // true
console.log(tree.has(1)); // false
// 로그 시간 = 이진 탐색
// times -> 선형 로그 시간으로 충분히 가능
// 우리는 특정 값을 찾는 것이 아닙니다.
// 우리가 찾는 것은 최소 몇 분에 모든 심사가 끝나는가?
// - 결정 문제 = 이진 탐색 = 파라메트릭 서치(Parametric Search)
// 최소 1분에서 10억분 * n 사이
// 면접관들이 몇 명을 처리하는가?
// 처리 가능한 입국자 n보다 작다면, 분을 올려야 하고, 입국자가 n보다 크면 분을 낮춰야 한다.
// 시간 / 심사시간 = 심사관 당 처리 가능한 입국자 수
function solution(n, times) {
// 오름차순
const sortedTimes = times.sort((a, b) => a - b); // O(n log n)
let left = 1;
let right = sortedTimes[sortedTimes.length - 1] * n;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
// sum([시간 / 심사시간])
const sum = times.reduce((acc, time) => acc + Math.floor(mid / time), 0);
if (sum < n) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}