-
[프로그래머스] 42883_큰 수 만들기(c++)Problem Solving/PROGRAMMERS 2019. 11. 12. 20:40
문제 설명
어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.
예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.
문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.
제한 조건
- number는 1자리 이상, 1,000,000자리 이하인 숫자입니다.
- k는 1 이상 number의 자릿수 미만인 자연수입니다.
입출력 예
numberkreturn
1924 2 94 1231234 3 3234 4177252841 4 775841
#C++ 첫 접근
- 처음 접근은 들어온 수를 오름차순으로 정렬하고 k개의 개수만큼 삭제하면 된다고 생각함.
- 그래서 sv(sorted vector)를 선언하고 sort()를 실행함. 원소들이 오름차순으로 정렬됨.
- sv와 nv를 비교하여 일치하는 곳의 숫자를 지우는 방식으로 구현함.
#include <string> #include <vector> #include <iostream> #include <algorithm> #include <cstdlib> using namespace std; string solution(string number, int k) { string answer = ""; vector<char> nv, sv; for(int i = 0; i < number.length(); i++) { nv.push_back(number.at(i)); sv.push_back(number.at(i)); } sort(sv.begin(), sv.end()); for(int i = 0; i < k; i++){ char dNum = sv[i]; for(int j = 0; j < nv.size(); j++){ if(dNum == nv[j]) { nv.erase(nv.begin() + j); break; } } } for(int i = 0; i < nv.size(); i++) answer += nv[i]; return answer; }
실행 결과
테스트 케이스가 일부만 통과됨. 예제를 다시 살펴보고 기존에 들어온 수의 순서가 바뀌면 안된다는 것을 알게 됨.
#C++ 두 번째 접근
- number로 넘어온 데이터를 한자리(한개)씩 처리하기로 결정함.
- 그래서 현재 처리할 데이터와 기존 데이터를 비교하여 삽입, 삭제를 수행하기 위해 스택 자료구조를 사용함.
- 기존에 삽입된 원소보다 처리할 원소가 크다면 기존 원소를 삭제하고 현재 데이터를 삽입함.
- 숫자의 맨 앞자리의 숫자가 크면 클 수록 좋기 때문임.
- 이때 주의할 점은 삭제 가능한 크기를 담은 k 이상으로 삭제 연산이 일어나면 안되기 때문에 조건으로 걸어줘야 함.
- 또한, 처리할 데이터가 스택의 top에 있는 원소보다 큰 경우에 삭제를 수행하는데 반복적으로 top의 원소와 대소 비교 연산을 해야함.
- 입출력 예제 3 (4177252841) 을 보자. 처음에 스택에는 4가 삽입되고 그 뒤로 1이 push됨. 그리고 7이 들어올 때 1과 비교해서 7이 더 크기 때문에 pop이 수행됨. 데이터 하나 당 loop를 한번만 실행한다면 아래와 같은 순서로 stack 연산이 일어남.
- 이렇게 될 경우 가장 맨 앞자리의 수가 7이 아닌 4가 되기 때문에 가장 큰 수를 만든다고 할 수 없음.
2 push 2 pop 8 push 2 push 2 pop 5 push 5 5 5 7 push 7 7 7 7 7 7 1 push 1 pop 7 push 7 7 7 7 7 7 7 4 push 4 4 4 4 4 4 4 4 4 4 [stack 상황]
- 따라서, 비교를 수행했을 때 스택에 있는 원소를 삭제하고 계속 top에 있는 원소와 비교하여 삭제를 처리해주어야 함. 그래서 whlie문을 통해 삭제 후에도 top의 원소를 반복적으로 비교할 수 있도록 구현함.
2 push 2 pop 2 push 2 pop 5 push 5 5 1 push 1 pop 7 push 7 7 7 7 7 4 push 4 4 4 pop 7 push 7 7 7 7 7 7 [stack 상황]
- 그리고 k개만큼 삭제를 못한 경우도 있기 때문에 k개와 같아지도록 pop 연산을 수행함.
- 이것이 가능한 이유는 스택에 들어간 원소는 이전 원소보다 작거나 같다는 의미이기 때문임.
#include <string> #include <vector> #include <stack> #include <algorithm> using namespace std; string solution(string number, int k) { //큰 수 만들기 - success string answer = ""; int size = number.length() - k; stack<char> st; for(int i = 0; i < number.length(); i++){ char cur = number.at(i); //처리할 숫자 while(!st.empty() && k > 0){ // char top = st.top(); //스택의 가장 맨 위의 값 if(top < cur){ //값 비교 st.pop(); //처리할 값이 더 크기 때문에 pop 수행 k--; //제거 횟수 감소 } else break; //비교할 때 값이 같거나 스택에 있는 값이 더 큰 경우 } st.push(cur); //처리하는 값이 큰 경우를 제외하고 모든 경우 스택에 삽입 } //처리하고 남은 스택의 사이즈와 제거하고 남아야하는 수가 같아야함. //아닌 경우 같아질 때까지 제거(스택에 남아있다는 것은 제거할 원소보다 이전 원소가 작거나 같다는 의미이므로) while(st.size() != size) st.pop(); while(!st.empty()){ //결과값 생성 answer += st.top(); st.pop(); } //위에서 거꾸로 값이 이어졌기 때문에 reverse 수행 reverse(answer.begin(), answer.end()); return answer; }
실행 결과
'Problem Solving > PROGRAMMERS' 카테고리의 다른 글
[프로그래머스] 42746_가장 큰 수(c++) (1) 2019.11.25 [프로그래머스] 12905_가장 큰 정사각형 찾기(c++) (0) 2019.11.12 [프로그래머스] 43162_네트워크(java, c++) (0) 2019.11.12 [프로그래머스] 42587_프린터(java, c++) (0) 2019.11.10