Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript로 기존 숫자를 재사용해 가장 가까운 다음 시간 구하기

문제 소개

"HH:MM" 형식으로 시간을 나타내는 문자열을 입력받아, 해당 시간에 포함된 숫자들을 재사용하여 만들 수 있는 가장 가까운 다음 시간을 반환하는 JavaScript 함수를 작성해야 합니다. 각 숫자는 제한 없이 몇 번이든 반복해서 사용할 수 있다는 점이 핵심입니다.

예를 들어 함수에 다음과 같은 값이 입력되었다고 가정해 보겠습니다.

입력

const time = '19:34';

출력

const output = '19:39';

출력 설명

숫자 1, 9, 3, 4로 만들 수 있는 다음으로 가장 가까운 시간은 19:39이며, 이는 현재 시간보다 5분 뒤입니다. 같은 숫자로 만들 수 있는 19:33도 존재하지만, 이 시간은 23시간 59분 뒤에 해당하므로 정답이 될 수 없습니다.

해결 아이디어

이 문제는 시간을 구성하는 네 개의 자릿수를 뒤에서부터 앞으로(분의 일의 자리 → 분의 십의 자리 → 시의 일의 자리 → 시의 십의 자리) 하나씩 검사하며, 가능한 한 작은 변화만으로 시간을 앞당기는 그리디(Greedy) 방식으로 해결할 수 있습니다.

구체적인 절차는 다음과 같습니다.

  1. 네 개의 숫자를 오름차순으로 정렬해 둡니다.
  2. 분의 일의 자리(d): 현재 값보다 큰 숫자가 있는지 확인하고, 있다면 교체합니다.
  3. 분의 십의 자리(c): 분은 59까지 표현되므로 5 이하인 숫자 중 현재 값보다 큰 것으로 교체하고, 일의 자리는 최솟값으로 초기화합니다.
  4. 시의 일의 자리(b): 교체 후 전체 시(hour) 값이 유효 범위를 벗어나지 않는지 확인하며 교체합니다.
  5. 시의 십의 자리(a): 시는 23까지 표현되므로 2 이하인 숫자 중 현재 값보다 큰 것으로 교체합니다.
  6. 어떤 자릿수도 더 크게 만들 수 없다면, 모든 자릿수를 최솟값으로 채운 값(예: 11:11)이 하루가 지난 후의 가장 가까운 시간입니다.

구현 코드

위 아이디어를 바탕으로 작성한 코드는 다음과 같습니다.

const time = '19:34';

const findClosestTime = (time = '') => {
   // 시간 문자열을 네 개의 숫자로 분리
   const [a, b, c, d] = [time[0], time[1], time[3], time[4]].map(x => Number(x));

   // 숫자들을 오름차순으로 정렬
   const sorted = [a, b, c, d].sort((x, y) => x - y);

   // 1) 분의 일의 자리(d)를 더 큰 숫자로 교체
   const d2 = sorted.find(x => x > d);
   if (d2 > d) {
      return `${a}${b}:${c}${d2}`;
   }

   const min = Math.min(a, b, c, d);

   // 2) 분의 십의 자리(c)를 교체 (분은 59 이하)
   const c2 = sorted.find(x => x > c && x <= 5);
   if (c2 > c) {
      return `${a}${b}:${c2}${min}`;
   }

   // 3) 시의 일의 자리(b)를 교체
   const b2 = sorted.find(x => x > b && a * 10 + x <= 24);
   if (b2 > b) {
      return `${a}${b2}:${min}${min}`;
   }

   // 4) 시의 십의 자리(a)를 교체 (시는 23 이하)
   const a2 = sorted.find(x => x > a && x <= 2);
   if (a2 > a) {
      return `${a2}${min}:${min}${min}`;
   }

   // 5) 어떤 자릿수도 증가시킬 수 없는 경우
   return `${min}${min}:${min}${min}`
};
console.log(findClosestTime(time));

실행 결과

19:39

마무리

이 풀이의 장점은 모든 가능한 시간 조합을 탐색하지 않고도 답을 찾을 수 있다는 것입니다. 자릿수를 뒤에서부터 우선적으로 조정하기 때문에 항상 "가장 가까운 다음 시간"을 보장하며, 시간 복잡도 역시 상수 시간(O(1))으로 매우 효율적입니다. 비슷한 유형의 자릿수 조작 문제를 풀 때도 동일한 접근 방식을 활용할 수 있으니 참고해 보시기 바랍니다.