[프로그래머스][C++] 110 옮기기
110 옮기기
문제 링크
분석
각 문자열에 대해 “110”을 임의의 위치에 삽입하여 사전순으로 가장 앞서는 문자의 배열을 만들고자 합니다.
문자열에서 “110” 패턴을 찾아서 임의의 위치에 다시 삽입해야합니다.
s
는 변형시킬 문자열 여러개가 들어있는 문자열 배열입니다.
문자열을 순회하여 “110” 패턴을 찾아 제거하고, 제거한 횟수를 기록합니다.
문자열에서 가장 마지막에 등장하는 ‘0’의 위치를 찾습니다.
이 위치 바로 뒤에 제거한 “110” 패턴들을 삽입하면 사전순으로 가장 앞서는 문자열을 만들 수 있습니다.
만약, ‘0’이 없는 경우 문자열의 맨 앞에 “110” 패턴들을 삽입하면 됩니다.
풀이
#include <string>
#include <vector>
#include <stack>
using namespace std;
vector<string> solution(vector<string> s) {
vector<string> answer;
// s의 각 문자열을 순회
for (auto str : s)
{
// 문자를 담을 스택
stack<char> st;
// "110" 패턴이 발견된 횟수
int count = 0;
// 현재 문자열의 모든 문자를 순회
for (auto c : str)
{
// 스택에 현재 문자 저장
st.push(c);
// 스택에 3개 이상의 문자가 쌓였다면 마지막 문자가 "110"인지 확인한다.
if (st.size() >= 3)
{
char third = st.top();
st.pop();
char second = st.top();
st.pop();
char first = st.top();
st.pop();
// 마지막 3개 문자가 "110"인 경우 패턴을 제거하고, count를 증가합니다.
if (first == '1' && second == '1' && third == '0')
{
++count;
}
else
{
st.push(first);
st.push(second);
st.push(third);
}
}
}
// 스택에 남은 문자들을 문자열로 복원합니다.
string temp = "";
while (!st.empty())
{
// 스택이므로 역순으로 처리합니다.
temp = st.top() + temp;
st.pop();
}
// "110"을 count만큼 반복해서 생성합니다.
string insertStr = "";
for (int i = 0; i < count; ++i)
{
insertStr += "110";
}
// temp에서 0이 마지막으로 등장한 위치를 찾습니다.
int pos = temp.find_last_of('0');
// 0이 없는 경우 문자열의 맨 앞에 삽입하고, 있는 경우 바로 뒤에 삽입합니다.
if (pos == string::npos)
{
temp = insertStr + temp;
}
else
{
temp.insert(pos + 1, insertStr);
}
// 현재 문자열에 대한 처리 결과를 저장합니다.
answer.push_back(temp);
}
return answer;
}
성능 요약
시간 복잡도는 $O(n \times l)$입니다.
s
의 각 문자열을 순회하는 반복문 $O(n)$- 현재 문자열의 모든 문자를 순회하여 “110”을 찾는 반복문 $O(l)$
l
은 현재 문자열의 길이입니다.
- 스택에 남아있는 문자열을 복구하는 반복문 $O(l)$
- “110” 문자열을 생성하고 삽입하는 반복문 $O(l \div 3) \approx O(l)$
- $O(n) \times (O(l) + O(l) + O(l))$
공간 복잡도는 $O(n \times l)$입니다.
- 문자를 담을 스택
stack<char> st
$O(l)$ - 스택에 남은 문자들을 문자열로 복원하는 문자열
string temp
$O(l)$ - 제거된 “110”을 생성하는 반복문 $O(l)$
- 결과를 저장하는
answer
$O(n \times l)$
테스트 성능
테스트 1 〉 통과 (77.45ms, 9.06MB)
테스트 2 〉 통과 (159.72ms, 9.16MB)
테스트 3 〉 통과 (451.15ms, 7.95MB)
테스트 4 〉 통과 (5850.69ms, 11MB)
테스트 5 〉 통과 (34.14ms, 9.37MB)
테스트 6 〉 통과 (55.30ms, 9.36MB)
테스트 7 〉 통과 (171.29ms, 7.71MB)
테스트 8 〉 통과 (207.46ms, 7.04MB)
테스트 9 〉 통과 (63.44ms, 27MB)
테스트 10 〉 통과 (62.80ms, 26.3MB)
테스트 11 〉 통과 (82.18ms, 24.9MB)
테스트 12 〉 통과 (61.41ms, 24.8MB)
테스트 13 〉 통과 (62.63ms, 23.8MB)
테스트 14 〉 통과 (61.26ms, 23.8MB)
테스트 15 〉 통과 (62.11ms, 23.7MB)
테스트 16 〉 통과 (60.53ms, 23.7MB)
테스트 17 〉 통과 (54.35ms, 22.1MB)
테스트 18 〉 통과 (10.70ms, 9.29MB)
테스트 19 〉 통과 (12.85ms, 10.8MB)
테스트 20 〉 통과 (9.28ms, 8.21MB)
테스트 21 〉 통과 (12.62ms, 11MB)
댓글남기기