정수 배열 numbers가 주어질 때, 원소들을 이어 붙여 만들 수 있는 가장 큰 수를 문자열로 반환하는 문제이다.
numbers = [3, 30, 34, 5, 9] → "9534330"
numbers = [0, 0, 0] → "0"
처음에 내림차순 정렬로 풀고 틀렸다.
단순 내림차순 → [9, 5, 34, 30, 3] → "9534303"
정답 → [9, 5, 34, 3, 30] → "9534330" ← 더 큰 수!
30과 3 중 어떤 게 앞에 와야 하는지 확인해보면
3 앞 → "330"
30 앞 → "303"
330 > 303 → 3이 앞에 와야 한다
즉 두 숫자 a, b를 이어붙였을 때 ab > ba이면 a가 앞에 오도록 정렬해야 한다. 이를 Java의 Comparator로 표현하면 아래와 같다.
Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));
compareTo()는 문자열을 사전순으로 비교하는 메서드이다.
(b + a).compareTo(a + b)가 양수 → b + a가 더 큼 → b를 앞으로a + b가 더 큼 → a를 앞으로int[]를 바로 문자열 비교에 쓸 수 없기 때문에, 먼저 String[]로 변환해야 한다는 것이다.입력값이 모두 0일 경우도 생각해서 엣지케이스도 추가해야한다.
구체적으로 정리한 풀이 흐름:
int[] → String[]로 변환(b + a).compareTo(a + b) 커스텀 정렬String.join()으로 배열 합치기"0"으로 시작하면 "0" 반환 (엣지케이스)import java.util.Arrays;
class Solution {
public String solution(int[] numbers) {
String[] arr = new String[numbers.length];
for (int i = 0; i < numbers.length; i++) {
arr[i] = String.valueOf(numbers[i]);
}
Arrays.sort(arr, (a, b) -> (b + a).compareTo(a + b));
String result = String.join("", arr);
if (result.startsWith("0")) return "0";
return result;
}
}