우선 정렬 알고리즘에 관한 문제이고 문제는 아래와 같다.

우선 문제를 간단하게 분석해보자면, numbers의 길이가 100,000이기 때문에 단순히 for문을 사용하거나 문자열로 나타내기 위해 단순히 문자열의 순열 (next_permutation) 방식으로는 시간 초과가 날 것이라 생각했다.
100,000의 길이면 nlogn 시간 복잡도를 가진 정렬을 상한선으로 택해야 하는데, C++에서 의 sort() 함수의 시간 복잡도가 nlogn이기 때문에 해당 sort() 함수를 잘 이용해보면 될 것이라 생각했다.
sort 함수를 기존 정렬 방식이 아닌 주어진 문제에 맞는 정렬 방식을 사용하고 싶다면 sort 의 3번째 파라미터에 정렬 조건에 대한 비교 함수를 넣으면 자신이 원하는 정렬을 수행 가능하기 때문에 nlogn 시간 복잡도를 유지하면서 커스텀을 할 수 있다는 것을 알고 있었다.
주어진 입출력의 예를 한번 살펴보면,
[3, 30, 34, 5, 9] 에서 가장 큰 수가 되려면 9534330인데, 정렬 시 두 개의 값에 대해서 어떤 식으로 비교를 해야 가장 큰 수로 정렬이 가능할지 생각해보니 아래와 같았다.
3,30 -> 330, 303 비교했을 때 330이 더 크기 때문에 두 수를 a, b로 가정하면 a + b > b + a 일 때 참인 경우이다.
좀 더 이해하기 쉽도록 플로우를 구성해보면,,
3, 30 -> 330이 더 크기 때문에 그대로 유지
30, 34 -> 3430이 더 크기 때문에 스위칭
30, 5 -> 530이 더 크기 때문에 스위칭
30, 9 -> 930이 더 크기 때문에 스위칭,, 여기까지 했을 때 -> [3,34,5,9,30] 이렇게 정렬이 될 것이다. 아무튼 비교 함수를 a + b > b + a로 만들었을 때 결국에는 [9, 5, 34, 3, 30]로 정렬될 수 있다. + 만약 정렬 시 가장 앞에 오는 수가 0일 경우에는 0으로 return 되어야 한다.
이런 생각을 바탕으로 작성한 코드는 아래와 같다.
// numbers의 길이가 100,000 -> 시간 복잡도 nlogn으로 풀어야 할듯
// algorithm sort() 함수가 nlogn 시간 복잡도를 지님
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
bool cmp(const string &a, const string &b){
return a+b > b+a;
}
string solution(vector<int> numbers) {
string answer = "";
vector<string> tmp(numbers.size());
for(int i = 0; i < numbers.size(); i++){
tmp[i] = to_string(numbers[i]);
}
sort(tmp.begin(), tmp.end(), cmp);
if(tmp[0] == "0") answer = "0";
else{
for(int i = 0; i < tmp.size(); i++){
answer += tmp[i];
}
}
return answer;
}'Developer > Algorithm' 카테고리의 다른 글
| 프로그래머스 - 구명보트 (Level2, Greedy) (0) | 2024.09.20 |
|---|