반응형
https://programmers.co.kr/learn/courses/30/lessons/17683
코딩테스트 연습 - [3차] 방금그곡
방금그곡 라디오를 자주 듣는 네오는 라디오에서 방금 나왔던 음악이 무슨 음악인지 궁금해질 때가 많다. 그럴 때 네오는 다음 포털의 '방금그곡' 서비스를 이용하곤 한다. 방금그곡에서는 TV,
programmers.co.kr
풀이
이 문제는 재생시간을 계산해서 그 시간에 맞는 전체 악보를 생성하는 것이 중요한 문제입니다.
저는 악보 생성에서 삽질을 너무 했습니다ㅠㅠ
제가 이용한 알고리즘은 다음과 같습니다.
- 시작시간, 종료시간을 모두 분 단위로 변환해 재생시간 구함
- 재생시간에 맞게 재생되는 전체 악보 생성 (# 을 고려해서 몇분짜리 악보인지 구해야함)
- 전체 악보에서 문자열 m이 등장하는 위치들을 모두 찾아서 저장해둠
- 각각의 등장하는 위치들에 대해서 m이 등장한 후에 '#'이 이어지는 경우는 동일한 것이 등장한다고 볼 수 없음
- 등장하는 것을 찾은 경우 <Key : 재생시간, Value:제목>으로 HashMap을 생성 (이때 재생시간이 같은 경우 먼저 입력된 음악 제목이 답이기 때문에 저는 HashMap에 중복여부를 확인하기 귀찮아서 그냥 musicinfos를 뒤부터 탐색하고 앞으로 가면서 같은 재생시간이 있는 경우 업데이트 될 수 있도록하여 결국 앞값이 남게 구현했습니다.)
- 모든 musicinfos 탐색 후 재생시간 가장 큰 값을 찾음. HashMap이 빈 경우 answer = "(None)"
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
class Solution {
public String solution(String m, String[] musicinfos) {
String answer = "";
Map<Integer, String> map1 = new HashMap<>();
int size = musicinfos.length;
//재생시간 동일한 경우 먼저 입력된 제목을 답으로 하기 위해 musicinfos를 뒤부터 탐색
for(int j=size-1; j>=0; j--){
String data = musicinfos[j];
ArrayList<Integer> idxList = new ArrayList<Integer> (); //등장위치
String[] array = data.split(","); //시작시간, 끝시간, 제목, 악보
//시간 계산
String[] s_time = array[0].split(":");
String[] e_time = array[1].split(":");
//분으로 변환
int s_hour = Integer.parseInt(s_time[0]);
int s_min = Integer.parseInt(s_time[1]);
int e_hour = Integer.parseInt(e_time[0]);
int e_min = Integer.parseInt(e_time[1]);
s_min = s_min+s_hour*60;
e_min = e_min+e_hour*60;
int total_time = e_min - s_min;
//#개수 count
int cnt=0;
for(int i=0; i<array[3].length(); i++) {
if(array[3].charAt(i)=='#') {
cnt++;
}
}
String sheet = "";
int play_time = total_time;
int play_len = array[3].length()-cnt;
//재생시간이 악보 길이보다 긴 경우
while(play_time >= play_len){
sheet += array[3];
play_time -= play_len;
}
//위의 처리 후 남은 재생시간이 있는 경우
int end_idx=-1;
if(play_time < play_len){
for(int i=0; i<array[3].length(); i++){
sheet+=array[3].charAt(i);
if(i == array[3].length()-1)
continue;
//다음꺼가 #인 경우 추가
if(array[3].charAt(i+1) == '#'){
sheet+=array[3].charAt(i+1);
i++;
}
play_time--;
if(play_time < 0){
end_idx = i;
break;
}
}
}
if(end_idx!=-1 && end_idx<array[3].length()-1){
if(array[3].charAt(end_idx+1) == '#')
sheet+=array[3].charAt(end_idx+1);
}
//등장위치 모두 찾음
int idx = sheet.indexOf(m);
while(idx != -1){
idxList.add(idx);
idx = sheet.indexOf(m, idx+m.length());
}
if(idxList.size() == 0)
continue;
//등장 안함.
int sw = 0;
//등장하는데, 뒤에 #이 붙는지 확인
for(int i=0; i<idxList.size(); i++){
int check = idxList.get(i)+m.length();
if(check >= sheet.length())
break;
if(sheet.charAt(check)!='#'){
sw = 1;
break;
}
}
if(sw == 0)
continue;
//추가
map1.put(total_time, array[2]);
}
//Map 확인
Set<Map.Entry<Integer, String>> entries = map1.entrySet();
int time = 0;
for(Map.Entry<Integer,String> tempEntry: entries) {
if(time < tempEntry.getKey()){
time = tempEntry.getKey();
answer = tempEntry.getValue();
}
}
//Map이 비었던 경우는 time이 그대로 0으로 남게됨.
if(time == 0)
answer = "(None)";
return answer;
}
}
728x90
반응형
'알고리즘 > PS - 프로그래머스' 카테고리의 다른 글
[프로그래머스 - Java] 행렬 테두리 회전하기 (0) | 2021.08.06 |
---|---|
[프로그래머스 - Java] 배달 (0) | 2021.08.05 |
[프로그래머스 - Java] 스킬트리 (0) | 2021.08.05 |
[프로그래머스 - C++] 블록 이동하기 (0) | 2021.08.03 |
[프로그래머스 - C++] 기지국 설치 (0) | 2021.08.02 |