-
문제
https://school.programmers.co.kr/learn/courses/30/lessons/42746
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 해석
접근 방법
주어진 숫자들을 배치했을 때 만들 수 있는 가장 큰 수를 계산해 문자열로 출력하는 문제입니다.
숫자의 배치에 따른 대소를 비교해 배열을 정렬합니다.
여기서 숫자를 문자로 / 문자를 숫자로 변환할 때 예외 케이스에 대해 생각해야 합니다.
풀이 과정
가장 큰 수를 만들기 위해서 배열을 정렬합니다.
정렬은 앞뒤 배치에 따른 숫자의 크기를 기준으로 합니다.
숫자를 문자로 변환한 a, b에 대해서 ab보다 ba가 크면 b를 앞으로 보내는 방식입니다.
예를 들어 주어진 배열이 [10, 1] 이라면 정렬은 다음과 같이 일어납니다.
a: 10 / b: 1
ab: 101
ba: 110
ab < ba 이므로 b를 앞으로 정렬해 [1, 10]이 됨최종적으로 join()을 사용해 배열을 문자열로 합치면 문제에서 요구하는 정답이 됩니다.
여기서 여러 개의 반례가 존재하는데, 순서대로 살펴보겠습니다.
1. (두 개 이상의) 주어진 숫자가 모두 0인 경우
만약 주어진 배열이 [0, 0, 0, 0] 이라면 반환값은 다음과 같습니다.
문제에서 요구하는 반환값: "0"
실제 반환값: "0000"이를 위해 join()한 문자열을 숫자로 변환한 후, 다시 문자열로 변환한다면 위 반례는 해결됩니다.
"0000" > 0 > "0"
하지만 이 방법에도 역시 반례가 존재합니다.
2. 변환한 숫자가 지나치게 큰 수일 경우 (Number.MAX_SAFE_INTEGER)
자바스크립트의 숫자 타입은 Number.MAX_SAFE_INTEGER(2^53 - 1) 이상의 수에 대해 유효성을 보장하지 않습니다.
또한 일정 숫자 이상이 되면 exponential을 사용해 표기됩니다.
즉 join()한 문자열의 길이가 일정 길이 이상일 경우에는 숫자로의 변환이 제대로 일어나지 않는다는 의미입니다.
만약 주어진 배열이 [11111111111, 00000000000] 이라면 반환값은 다음과 같습니다.
문제에서 요구하는 반환값: "1111111111100000000000"
실제 반환값: "1.1111111111e+21"결론적으로,
위 두 가지의 반례를 모두 충족하기 위해서 합친 문자열에 "0"의 존재 여부에 따라 반환값을 다르게 설정하면 됩니다.
1. 합친 문자열에 "0"이 존재하지 않을 때는 문자열 그대로 반환합니다.
2. "0"만 존재할 때는 "0"을 반환합니다.
전체 코드
function solution(numbers) { const newNums = numbers.map((n) => String(n)); const sortNums = (a, b) => { const ab = a + b; const ba = b + a; return Number(ba) - Number(ab); } newNums.sort(sortNums); return newNums.join('').match(/[1-9]/) ? newNums.join('') : "0"; }회고
- Number.MAX_SAFE_INTEGER에 대해 더 자세히 알아보자. (관련 검색어: 배정밀도 64비트 부동소수점)
'Algorithm > JavaScript' 카테고리의 다른 글
[PRO] 프로그래머스 Lv.2 게임 맵 최단 거리 (Javascript) (3) 2024.11.15 [PRO] 프로그래머스 Lv.2 롤케이크 자르기 (Javascript) (2) 2024.11.13 [PRO] 프로그래머스 Lv.2 2개 이하로 다른 비트 (Javascript) (1) 2024.11.11 [PRO] 프로그래머스 Lv.2 타겟 넘버 (Javascript) (3) 2024.11.10 [PRO] 프로그래머스 Lv.2 땅따먹기 (Javascript) (0) 2024.11.09