[프로그래머스] LV 2 방금그곡

https://school.programmers.co.kr/learn/courses/30/lessons/17683

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

접근 방법

  1. 최대 00:00 ~ 23:59 동안의 멜로디를 기억하며, 해당 멜로디가 일치하는 노래를 찾아 제목을 반환한다
  2. 그런데 지문엔 " C, C#, D, D#, E, F, F#, G, G#, A, A#, B  " 의 음만 입력될것이라고 했지만 E#과 B#도 고려해야한다.
  3. 음을 하나하나 매번 비교하는건 복잡하고 OOB가 발생하기 쉬울거같다.
    1. C ~ B#까지의 음을 0 ~ 13으로 번호를 부여하고 int 배열로 바꾸어 비교를 진행했다
  4. [비교 과정] 먼저, info의 음에서 m(기억한 멜로디)의 첫번째 음과 같을때까지 찾는다.
    1. 같은것을 찾는다면 m의 길이만큼 같은지 비교한다.
    2. 다르다면 4로 돌아가 다시 찾는다
    3. 같다면 true를 반환한다.
  5. 입력순서대로 음악 재생 시간의 대소를 비교하며 ans에 대입하면 자연스럽게 우선순위를 만족할 수 있다.

코드

import java.util.*;
class Solution {
    Map<String, Integer> map;
    public String solution(String m, String[] musicinfos) {
        init();
        int maxD = 0;
        String ans = null;
        int[] mu = changeMusic(m);
        
        for(String musicInfo: musicinfos){
            String[] info = musicInfo.split(",");
            int startTime = getTime(info[0]);
            int endTime = getTime(info[1]);
            int duration = endTime - startTime; // 1분에 음이 1개씩 진행
            
            String name = info[2];
            int[] music = changeMusic(info[3]);
            
            boolean b = check(mu, music, duration);
            
            if(b && duration > maxD){
                ans = name;
                maxD = duration;
            }
        }
        
        return ans == null ? "(None)" : ans;
    }
    boolean check(int[] m, int[] music, int d){
        int idx = 0;
        out:
        while(d-- >0){
            if(m[0] != music[idx]){
                idx = (idx+1) % music.length;
                continue;
            }
            //같은곳 찾았다
            for(int i = 0 ; i< m.length ; i++){
                if(m[i] != music[idx]) continue out;
                
                idx = (idx+1) % music.length;
                d--;
            }
            return true;
        }
        
        return false;
    }
    int getTime(String t){
        String[] time = t.split(":");
        String h = time[0];
        String m = time[1];
        
        return Integer.parseInt(h) * 60 + Integer.parseInt(m);
    }
    int[] changeMusic(String music){
        List<Integer> list = new ArrayList<>();
        int n = music.length();
        
        for(int i = 0 ; i < n-1 ; i++){
            if(music.charAt(i+1) == '#'){
                list.add(map.get(music.substring(i, i+2)));
                i++;
            }else{
                list.add(map.get(music.substring(i, i+1)));
            }
        }
        if(music.charAt(n-1) != '#') list.add(map.get(music.substring(n-1, n)));
        return list.stream().mapToInt(Integer::intValue).toArray();
    }
    void init(){
        map = new HashMap<>();
        map.put("C",0);map.put("C#",1);
        map.put("D",2);map.put("D#",3);
        map.put("E",4);map.put("E#",5);
        map.put("F",6);map.put("F#",7);
        map.put("G",8);map.put("G#",9);
        map.put("A",10);map.put("A#",11);
        map.put("B",12);map.put("B#",13);
    }
}