문제를 보고 어떻게 풀지 감이 잘 안와서 일단 조합을 만드는 것으로 시도했다.
문제는 제한 조건에서 number가 1,000,000자리 이하인 숫자인데, 풀면서도 이건 시간 때문에 안되겠구나 생각을 했고,
실제 결과도 시간초과로 실패햇다.
#include <string>
#include <vector>
using namespace std;
int result[1000001];
int visit[1000001];
string answer = "";
void combination(const string number, int n, int r, int depth)
{
if(r == depth) {
string ans = "";
int cnt = 0;
for(int i=0; i<n; i++) {
if(i == result[cnt])
cnt++;
else
ans.push_back(number[i]);
}
if(answer.compare(ans) < 0)
answer = ans;
return;
}
int start = depth == 0 ? 0 : result[depth - 1];
for(int i=start;i<n;i++) {
if(visit[i] == 0) {
visit[i] = 1;
result[depth] = i;
combination(number, n, r, depth + 1);
visit[i] = 0;
}
}
}
string solution(string number, int k) {
int size = number.size();
combination(number, size, k, 0);
return answer;
}
O(n)만에 무조건 풀어야할 것 같아서 고민을 좀 하고 공부를 좀 했다...
string solution(string number, int k) {
int size = number.size();
string answer = "";
for(int i=0;i<size;i++) {
if(answer.empty()) {
answer.push_back(number[i]);
continue;
}
if(k > 0) {
int start = answer.size() - 1;
for(int j=start; j>=0; j--) {
if(k == 0)
break;
if(answer[j] < number[i]) {
k--;
answer.pop_back();
continue;
}
break;
}
}
answer.push_back(number[i]);
}
// 예외 처리
if(k != 0) {
while(1) {
if(k == 0)
break;
k--;
answer.pop_back();
}
}
return answer;
}
얻은 결과는 위 코드와 같다.
큰 흐름은 일단 앞에서부터 쭉 가면서 비교를 하면서 가장 큰 앞자리 숫자를 만들어주는 것이다.
예를 들어서 설명하자면,
"1924"의 경우
1의 경우.
다른 예제도 위와 같이 해주면 되는데,
number : 999 // k : 1 같은 경우 "99"가 답으로 나와야하는데 "999"로 나온다.
이를 위해서 따로 예외처리를 해줘야한다. (테스트 케이스 12번이 그러한 케이스인듯)
결과는 위와 같다.