Logo

Changchangwoo's blog

TIL
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec
Sun
Mon
Tue
Wed
Thu
Fri
Sat
Today I Learned를 기록하는 공간입니다. 🔥🔥🔥
잔디를 클릭하면 내용확인이 가능합니다.
Pinned

이분탐색 자료구조 문제풀이 연습

이분 탐색 문제 키워드

  • 정렬된 배열 / 오름·내림차순 보장

  • 최솟값 / 최댓값 / 가능한 값 중 최대·최소

  • ~할 수 있는가? / 조건을 만족하는지 판별

  • 조건을 바탕으로 추론하는 경우 매개변수 탐색

  • 정렬되어 있는 리스트에서, 탐색 번위를 절반씩 좁혀가며 데이터를 탐색하는 방법

  • 시작점, 끝점을 명시하고 중간지점을 이용하여 탐색 범위 설정

  • 로직 자체는 쉬운데, 접근 방법을 어떻게 해야할지 고민하는 문제들이 많음

  • 그리디와 접목하는 등

입국 심사

function solution(n, times) {
  let left = 1;
  let right = Math.max(...times) * n;
  while (left <= right) {
    let mid = Math.floor((left + right) / 2);

    let count = 0;
    for (const time of times) {
      count += Math.floor(mid / time);
    }
    if (count >= n) {
      right = mid - 1;
    } else {
      left = mid + 1;
    }
  }
  return left;
}
  • 문제의 범위가 괴랄함. 일단 일반적인 그리디로 하면 시간초과 나겠다 ⇒ 효율적 탐색방법 모색
  • 다음으로는 접근방법에 대한 추론
    • 시간을 기준으로 탐색 범위 설정 ⇒ 최소 1초, 최대 max(time) * n을 도출 필요
    • 시간을 times 내부 time으로 나누었을때의 총 합이 n이 될 수 있다는 것을 추론 ⇒ 이게 젤 어려워 진짜
    • 이후 mid값을 기준으로 이분탐색 동작, 이때 count ≥ n보다 크다면 범위를 줄일 필요가 있다는 것이니 right = mid - 1;
    • 시간의 최소값을 구하는거니까 환

공유기 설치

/*
구하는 값 => 가장 인접한 두 공유기 사이의 거리를 최대로 하는 프로그램
이분 탐색 기준 => 공유기 사이 거리
*/
const input = require("fs")
  .readFileSync("./dev/stdin")
  .toString()
  .trim()
  .split("\n");
const [N, C] = input.shift().split(" ").map(Number);
const arr = input.map((item) => +item).sort((a, b) => a - b);
left = 1;
right = arr[N - 1] - arr[0];
while (left <= right) {
  let mid = Math.floor((left + right) / 2);
  let prev = arr[0];
  let count = 1;
  for (let i = 0; i < N; i++) {
    if (arr[i] - prev >= mid) {
      prev = arr[i];
      count++;
    }
  }
  if (count >= C) {
    left = mid + 1;
  } else {
    right = mid - 1;
  }
}
console.log(right);
  • 그리디 처럼 보이지만 이분 탐색이 필요한 문제
  • 공유기 사이의 거리를 최대로 하는 값을 반환해야함. 공유기 사이의 거리를 mid값으로 설정
  • 따라서 범위도 거리가 가장 가까운 1, 가장 큰 마지막 집 - 첫 집 (정렬을 통해 보장)
  • 이후, 그리디를 통해서 문제 탐색, 공유기를 설치하고, 다음 집에서의 거리가 임의로 설정한 공유기 사이 거리보다 크거나 같다면 count 증가
  • count 증가 값이 최대 설치개수보다 많아지는 경우 범위 넓히. count ≥ C라는건 현재 거리에서도 충분히 C만큼 설치가 가능하다 ⇒ 거리를 증가시켜야한다.
  • 결국 최댓값을 찾는 문제니 끝에 right 반환

⇒ 두 문제 모두 최대, 최소를 묻고 있다. 조건이 괴랄하고 범위를 묻는다면 이분탐색도 한번 고려