JavaScript | 프로그래머스 | Lv.2 가장 큰 수

설탕·2022년 6월 6일
0
post-thumbnail
post-custom-banner

프로그래머스 Lv.2 가장 큰 수 문제

문제 설명

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.

예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.

0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

제한 사항

  • numbers의 길이는 1 이상 100,000 이하입니다.
  • numbers의 원소는 0 이상 1,000 이하입니다.
  • 정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.

입출력 예

numbersreturn
[6, 10, 2]"6210"
[3, 30, 34, 5, 9]"9534330"

JavaScript 풀이

처음 풀었던 코드 🤔

function solution(numbers) {
  // 모든 원소가 0일 때 '0' 리턴
  if (numbers.every(each => each === 0)) return '0';
  
  const compareFunc = (prev, next) => {
    // 반복문으로 가장 큰 자릿수부터 비교, i는 자릿수
    let i = 0;
    while (i < 4) {
      // 가장 큰 자릿수 한 자리씩 변수에 담음
      let prevNum = +prev.toString()[i];
      let nextNum = +next.toString()[i];

      // 자릿수가 NaN이 아니고(자릿수가 있고) 수의 크기가 다르면 내림차순 정렬
      if (!Number.isNaN(prevNum) && !Number.isNaN(nextNum) && (prevNum !== nextNum)) {
        return nextNum - prevNum;
        
      // 자릿수가 다르면 앞뒤 수를 문자열로 변환해서 붙여보고 내림차순 정렬
      } else if (Number.isNaN(prevNum) || Number.isNaN(nextNum)) {
        let prevNext = +(prev.toString() + next.toString());
        let nextPrev = +(next.toString() + prev.toString());
        return nextPrev - prevNext;
      } else {
        i++;
      }
    }
  };
  return numbers.sort(compareFunc).join('');
}

처음 생각했던 알고리즘은, 정렬 함수 내에서

  1. while 반복문을 써서 가장 큰 자릿수부터(천의 자리 → 백의 자리 → 십의 자리 → 일의 자리) 차례로 비교한다.
  2. 자릿수가 다르면 숫자를 앞뒤로 붙여보고 ([232, 23] → 23223, 23232) 뒤앞 - 앞뒤를 반환한다.

그런데 풀고 나서 다른 사람들 풀이를 보고 훨씬 간결하게 풀 수 있다는 걸 알았다. 어차피 앞뒤로 붙여보고 비교할 거면 자릿수별로 나누지 않아도 되었다. 그래서 반복문을 다 없애고 앞뒤로 붙여보고 비교 정렬하는 함수만 남겼다.

리팩토링한 코드 🤓

function solution(numbers) {
    let answer = numbers
    	.sort((prev, next) => (`${next}` + `${prev}`) - (`${prev}` + `${next}`))
    	.join('');
    return +answer === 0 ? '0' : answer;
}
  • toString() 대신 템플릿 리터럴을 사용했다.
  • '00000'일 때 '0'을 반환하도록 하는 조건은 삼항연산자로 처리했다.

훨씬 간결하고, 잘 작동한다.

profile
공부 기록
post-custom-banner

0개의 댓글