Skip to main content

[level 3] 브라이언의 고민 - 1830

Intro

문제 링크

문제 설명

광고 문구 사이에 특수문자를 넣어 차단 시스템을 회피하는 패턴을 분석하여, 원래 문구를 복원하는 프로그램을 작성해야 합니다. 영문 대문자는 원래 문구, 소문자는 특수기호를 의미하며 규칙은 다음과 같습니다.

  • 규칙 1: 특정 단어를 선택하여 글자 사이마다 같은 기호를 넣습니다. ex) HELLO -> HaEaLaLaO
  • 규칙 2: 특정 단어를 선택하여 단어 앞뒤에 같은 기호를 넣습니다. ex) WORLD -> bWORLDb

위의 두 가지 규칙은 한 단어에 모두 적용될 수 있지만 같은 규칙은 두 번 적용될 수 없습니다. 한 번 쓰인 소문자는 다시 쓰일 수 없으며, 원래 문구에 있던 공백은 제거된 상태로 입력됩니다.

입력 형식

  • 입력은 문자열 변수 로 주어집니다.
  • 영문 대소문자로만 이루어져 있으며, 길이는 1,000 이하입니다.

출력 형식

  • 규칙 적용 전 원래 문구를 리턴합니다.
  • 단어 사이의 공백은 한 글자여야 하며, 불가능한 경우 "invalid"를 리턴합니다.

입출력 예시

sentenceanswer
"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