📌 문제
0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.
예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.
0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.
📌 제한사항
- numbers의 길이는 1 이상 100,000 이하입니다.
- numbers의 원소는 0 이상 1,000 이하입니다.
- 정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.
📌 입출력 예
numbers | return |
[6, 10, 2] | "6210" |
[3, 30, 34, 5, 9] | "9534330" |
📌 풀이
알아야 하는 것
- arr.map()
- arr.join()
- arr.filter
구할 것
- sort를 어떤 식으로 할 것인지?
1-1. 사전식 정렬
[10, 2, 6] [3, 30, 34, 5, 9]가 나와서 reverse를 하면 되는 줄 알았다.
[6, 2, 10]로 1번째 TC는 맞지만 [9, 5, 34, 30, 3]으로 2번째 TC는 30과 3의 위치가 바뀌지 않았다.
오기로 이렇게 10, 100, 1000으로 나눠 떨어지는 경우라면 그 원소를 삭제하고 추가하는 방식으로 진행해보았으나 당연히 실패했다.
if (nums[i] % 10 === 0) {
let num = nums[i];
nums.splice(i, 1);
nums.push(num);
}
애초에 이렇게 정렬하는 게 잘못된 접근인가? 하는 생각이 들었다.
예컨대 [10, 10, 1000]이 들어왔을 때 사전식 정렬+reverse를 하면 [1000, 10, 10]으로 원래 나와야 할 [10101000]이 나오지 않기 때문이었다. 3가지 TC에서 상이한 답이 나오는 걸 보면 너무 좁은 시야로 보고 있는 것 같아 다른 방식으로 정렬하기로 했다.
1-2. 문자열로 변환 후 정렬
내림차순을 하든 오름차순을 하든 사전식 정렬을 하든 0이 들어간 숫자가 걸리게 된다.
문제에서 문자열로 반환하라고 하기도 하고, 실제로 수를 만들 때도 숫자+숫자로 연산을 하는 게 아니라 문자+문자로 연산을 한다. 따라서 먼저 주어진 배열을 문자열 배열로 바꿔주고, 정렬을 다시 해봤다.
let nums = numbers.map((v) => String(v)).sort((a, b) => b + a - (a + b));
// 문자열로 배열 재생성 후 내림차순
예컨대 ['3', '30', '34', '5', '9'] 가 있으면 '3'+'30' 이랑 '30'+'3' 이랑 비교해서 더 큰 수대로 정렬했다.
그러면 330이랑 303으로 330이 더 커서 3, 30 순으로 정렬해 우선 원하는 반환값 모양을 반쯤 갖출 수 있게 된다.
이후 '3'+'34'와 '34'+'3'으로 34가 3보다 앞으로 오고... 이런 식으로 34330 처럼 계속 비교해 나가면 된다.
정렬을 이런 식으로 할 수도 있다, 계속 새로운 방향으로 생각해야 한다.
2. 결과값 반환
정렬한 후 문자열 배열로 있는 값을 join 메소드로 묶어 하나의 배열로 만든다.
그런데 이 때 문자열이기 때문에 ['0', '0', '0']의 경우 '000'으로 묶이는 요상한 결과가 발생한다.
이런 수는 없기 때문에 '0'만 나오게 해야 한다.
따라서 배열의 길이 === 0의 개수와 같다면 배열의 요소 전체가 0인 셈이니 "00", "000" 같은 결과라면 "0"만 나올 수 있도록 조건문을 하나 달아주고, 조건문에 해당되지 않으면 (전원 0이 아니면) 원래대로 답을 반환할 수 있게끔 코드를 작성했다.
function solution(numbers) {
let nums = numbers.map((v) => String(v)).sort((a, b) => b + a - (a + b));
let answer = nums.join("");
let countZero = nums.filter((e) => "0" === e).length;
if (answer.length === countZero) {
return "0";
} else {
return answer;
}
}
정렬하는 방법을 틀에 갇혀 생각하지 말고 구현하고자 하는 방식대로 고쳐 나가보자...
'⚙️ 코딩테스트' 카테고리의 다른 글
[JavaScript] 백준 코딩테스트 : 비밀번호 찾기 (0) | 2023.06.28 |
---|---|
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : H-Index (0) | 2023.06.27 |
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 소수 찾기 (0) | 2023.06.26 |
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 피로도 (0) | 2023.06.22 |
[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 카펫 (0) | 2023.06.21 |