본문 바로가기
자료구조 & 알고리즘/문제풀이

[3차] 방금그곡 - 2018 KAKAO BLIND RECRUITMENT (Java, Level 2)

by 넬준 2022. 6. 19.

처음 풀이

멜로디 전처리

 

#이 붙은 음은 글자 수가 달라 처리가 어려우므로 소문자로 바꿔준다.

 

publicString makeNewMelody(String melody) {  
    return melody.replace("C#", "c")  
            .replace("D#", "d")  
            .replace("F#", "f")  
            .replace("G#", "g")  
            .replace("A#", "a");  
}//makeNewMelody() end

 

연주 시간 구하기

 

public int getDuration(String startTime, String endTime) {  

    StringTokenizer stForDuration = new StringTokenizer(startTime, ":");  

    int startTimeHour = Integer.parseInt(stForDuration.nextToken());  
    int startTimeMin = Integer.parseInt(stForDuration.nextToken());  

    stForDuration = new StringTokenizer(endTime, ":");  

    int endTimeHour = Integer.parseInt(stForDuration.nextToken());  
    int endTimeMin = Integer.parseInt(stForDuration.nextToken());  

    return 60 * (endTimeHour-startTimeHour) + (endTimeMin-startTimeMin);  

}//getLength() end

 

멜로디 연주 시간 동안 연주하기

 

연주 시간을 곡 길이로 나눠 몫 만큼 곡을 반복해서 붙이고,
나머지 시간만큼 곡을 잘라서 붙인다.

 

StringBuilder sb = new StringBuilder();

public String playNewMelody(int duration, String newMelody) {  
    sb.setLength(0);  

    int newMelodyLength = newMelody.length();  

    for (int i = 0; i < duration/newMelodyLength; i++) {  
        sb.append(newMelody);  
    }//for end  

    int mod = duration % newMelodyLength;  

    sb.append(newMelody.substring(0, mod));  

    return sb.toString();  
}//playNewMelody() end

 

방금그곡 찾기

 

연주 시간(곡 길이x)과 곡 이름 정보를 담는 Song 클래스

 

static class Song {  
    int duration;  
    String name;  

    public Song(int duration, String name) {  
        this.duration = duration;  
        this.name = name;  
    }  
}

 

musicinfo에서 연주 시간, 이름, 멜로디를 얻는다.
멜로디는 전처리를 거친 뒤, 이를 연주 시간만큼 연주한다.
그 연주에 기억한 멜로디가 포함되었다면 songList에 담는다.

만일, songList에 곡이 없다면 "(None)" 리턴,
아니라면 곡을 연주 길이를 기준으로 내림차순으로 정렬 후 첫 번째 곡을 리턴한다. (List에 담았으니 담은 순서 유지)

 

public String solution(String m, String[] musicinfos) {  
    List<Song> songList = new ArrayList<>();  

    for (String musicinfo : musicinfos) {  
        StringTokenizer st = new StringTokenizer(musicinfo, ",");  

        String startTime = st.nextToken();  
        String endTime = st.nextToken();  
        String name = st.nextToken();  
        String melody = st.nextToken();  

        String newMelody = makeNewMelody(melody);  

        int duration = getDuration(startTime, endTime);  

        String playedNewMelody = playNewMelody(duration, newMelody);  

        if(playedNewMelody.contains(makeNewMelody(m))) { 
            songList.add(new Song(duration, name));  
        }  
    }//for end  

    if(songList.size()==0) {  
        return "(None)";  
    } else {  
        //연주 길이 내림차순 정렬  
        songList.sort(new Comparator<Song>() {  
        @Override  
        public int compare(Song o1, Song o2) {  
            return o2.duration-o1.duration;  
        }  
    });  
    //먼저 입력  
    return songList.get(0).name;  
    }  
}//solution() end

 

 

개선된 풀이

 

다른 풀이를 보니 Song 클래스를 사용하지 않아도 충분히 가능한 것을 알앗다.

 

Song 클래스에 담아서 연주 시간에 대해 한 번 더 작업하지 말고, 연주 시간이 이전까지 최고 연주 시간보다 클 때만 멜로디 작업한 후 기억한 멜로디가 포함되었는지 확인한다.

 

public String solution(String m, String[] musicinfos) {
    String answer = "(None)";
    
    int maxDuration = 0;
    
    for (String musicinfo : musicinfos) {  
        StringTokenizer st = new StringTokenizer(musicinfo, ",");  

        String startTime = st.nextToken();  
        String endTime = st.nextToken();  
        String name = st.nextToken();  
        String melody = st.nextToken();  

        int duration = getDuration(startTime, endTime);  

        if(duration > maxDuration) {  
            String newMelody = makeNewMelody(melody);  
            String playedNewMelody = playNewMelody(duration, newMelody);  

            if(playedNewMelody.contains(makeNewMelody(m))) {  
                answer = name;  
                maxDuration = duration;  
            }//if end  
         }//if end  
     }//for end  

     return answer;  
}//solution() end

 

 

대부분의 케이스에서 시간이 줄었다.

댓글