https://programmers.co.kr/learn/courses/30/lessons/17683#
단순히 문자열을 다루는 문제라서 그런지 어렵지는 않았다. 다만, 생각해야 하는 테스트케이스가 좀 있었다.
테스트케이스
찾고자 하는 멜로디 : m 기존 멜로디 (재생 시간에 대한 가공은 마침) : music
1. 찾고자 하는 멜로디와 비슷하지만 기존 음악 마지막에 #이 있는 경우
ex) m = ABCD, music = ABCD#
단순히 music에 m이 포함되었는지만 검사하게 되면 오답이다.
따라서 포함되었는지 검사하고 music과 m에서 겹친 문자열의 마지막 글자를 기준으로 바로 뒤에 #이 안붙어야 한다. (m의 맨 마지막 글자가 #인지 아닌지는 관계 없다.)
2. music의 첫 부분에는 비슷하지만 오답. 정답은 중간에 있는 경우
ex) m = ABC, music = ABC#ABC
1번에서 나온 케이스만 생각하면 오답이 된다. ABC가 문자열 내에 여러 번 존재할 수 있으니 이에 대해서 전부 돌려봐야 한다.
import java.util.*;
class Solution {
public String solution(String m, String[] musicinfos) {
String answer = "(None)";
int timeToAnswer = 0;
for (int i = 0; i < musicinfos.length; i++) {
String[] inputs = musicinfos[i].split(",");
String[] start = inputs[0].split(":");
String[] end = inputs[1].split(":");
String title = inputs[2];
String music = inputs[3];
int playTime = Integer.parseInt(end[0]) * 60 + Integer.parseInt(end[1]);
playTime -= Integer.parseInt(start[0]) * 60 + Integer.parseInt(start[1]);
List<String> melody = new ArrayList<>();
for (int j = 0; j < music.length(); j++) {
char c = music.charAt(j);
if (j < music.length() - 1) {
char next = music.charAt(j + 1);
if (next == '#') {
melody.add(Character.toString(c) + Character.toString(next));
j++;
continue;
}
}
melody.add(Character.toString(c));
}
int tempPlayTime = playTime;
if (tempPlayTime > melody.size()) {
StringBuilder sb = new StringBuilder();
while (tempPlayTime > melody.size()) {
sb.append(music);
tempPlayTime -= melody.size();
}
for (int j = 0; j < tempPlayTime; j++) {
sb.append(melody.get(j));
}
music = sb.toString();
} else {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < tempPlayTime; j++) {
sb.append(melody.get(j));
}
music = sb.toString();
}
int idx = music.indexOf(m);
while (idx > -1) {
if (music.length() == idx + m.length() || music.charAt(idx + m.length()) != '#') {
if (timeToAnswer < playTime) {
answer = title;
timeToAnswer= playTime;
}
}
idx = music.indexOf(m, idx + m.length());
}
}
return answer;
}
}