[level 3] 브라이언의 고민 - 1830
문제 설명
광고 문구 사이에 특수문자를 넣어 차단 시스템을 회피하는 패턴을 분석하여, 원래 문구를 복원하는 프로그램을 작성해야 합니다. 영문 대문자는 원래 문구, 소문자는 특수기호를 의미하며 규칙은 다음과 같습니다.
- 규칙 1: 특정 단어를 선택하여 글자 사이마다 같은 기호를 넣습니다. ex) HELLO -> HaEaLaLaO
- 규칙 2: 특정 단어를 선택하여 단어 앞뒤에 같은 기호를 넣습니다. ex) WORLD -> bWORLDb
위의 두 가지 규칙은 한 단어에 모두 적용될 수 있지만 같은 규칙은 두 번 적용될 수 없습니다. 한 번 쓰인 소문자는 다시 쓰일 수 없으며, 원래 문구에 있던 공백은 제거된 상태로 입력됩니다.
입력 형식
- 입력은 문자열 변수 로 주어집니다.
- 영문 대소문자로만 이루어져 있으며, 길이는 1,000 이하입니다.
출력 형식
- 규칙 적용 전 원래 문구를 리턴합니다.
- 단어 사이의 공백은 한 글자여야 하며, 불가능한 경우 "invalid"를 리턴합니다.
입출력 예시
| sentence | answer |
|---|---|
| "HaEaLaLaObWORLDb" | "HELLO WORLD" |
| "SpIpGpOpNpGJqOqA" | "SIGONG JOA" |
| "AxAxAxAoBoBoB" | "invalid" |
구현 코드
import java.util.*;
public class Solution {
public String solution(String sentence) {
StringBuilder answerList = new StringBuilder();
LinkedHashMap<Character, ArrayList<Integer>> lowerCount = new LinkedHashMap<>();
String invalid = "invalid";
try {
int size = sentence.length();
for(int i=0; i<size; i++){
char c = sentence.charAt(i);
if(Character.isLowerCase(c)){
if(!lowerCount.containsKey(c)){
lowerCount.put(c, new ArrayList<Integer>());
}
lowerCount.get(c).add(i);
}
}
int stringIdx = 0;
int startChar, endChar;
int lastStartChar = -1, lastEndChar = -1;
int startWord = 0, endWord = 0;
int lastStartWord= -1, lastEndWord = -1;
int count, distance;
int rule = 0;
ArrayList<Integer> temp;
for(char c : lowerCount.keySet()){
temp = lowerCount.get(c);
count = temp.size();
startChar = temp.get(0);
endChar = temp.get(count-1);
if(count == 1 || count >= 3){
for(int i=1; i<count; i++){
if(temp.get(i) - temp.get(i-1) != 2) return invalid;
}
rule = 1;
}
else if (count == 2){
distance = endChar - startChar;
if(distance == 2 && (endChar < lastEndChar && startChar > lastStartChar)){
rule = 1;
}
else if(distance >= 2){
rule = 2;
}
else return invalid;
}
if(rule == 1){
startWord = startChar -1;
endWord = endChar+1;
if(lastStartWord < startWord && lastEndWord > endWord){
if(startChar - lastStartChar == 2 && lastEndChar - endChar == 2){
continue;
}
else return invalid;
}
}
else if (rule == 2){
startWord = startChar;
endWord = endChar;
if(lastStartWord < startWord && lastEndWord > endWord) return invalid;
}
if(lastEndWord >= startWord) return invalid;
if(stringIdx < startWord){
answerList.append(makeWord(sentence,stringIdx,startWord-1));
answerList.append(" ");
}
answerList.append(makeWord(sentence,startWord,endWord));
answerList.append(" ");
lastStartWord = startWord;
lastEndWord = endWord;
lastStartChar = startChar;
lastEndChar = endChar;
stringIdx = endWord+1;
}
if(stringIdx < size){
answerList.append(makeWord(sentence,stringIdx,size-1));
}
}
catch (Exception e){
return invalid;
}
return answerList.toString().trim();
}
public String makeWord(String sentence, int start, int end){
String word = sentence.substring(start, end+1);
return word.replaceAll("[a-z]","");
}
}
성능 요약
메모리: 87.8 MB, 시간: 29.08 ms
채점결과
정확성: 100.0
합계: 100.0 / 100.0