๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Algorithm

[ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค LV3] ๋ฒ ์ŠคํŠธ ์•จ๋ฒ” (Hash, ํ•ด์‹œ)

๋ฐ˜์‘ํ˜•
SMALL

๐Ÿง LV3. ๋ฒ ์ŠคํŠธ ์•จ๋ฒ”

๋ฌธ์ œ ์„ค๋ช…

์ŠคํŠธ๋ฆฌ๋ฐ ์‚ฌ์ดํŠธ์—์„œ ์žฅ๋ฅด ๋ณ„๋กœ ๊ฐ€์žฅ ๋งŽ์ด ์žฌ์ƒ๋œ ๋…ธ๋ž˜๋ฅผ ๋‘ ๊ฐœ์”ฉ ๋ชจ์•„ ๋ฒ ์ŠคํŠธ ์•จ๋ฒ”์„ ์ถœ์‹œํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋ž˜๋Š” ๊ณ ์œ  ๋ฒˆํ˜ธ๋กœ ๊ตฌ๋ถ„ํ•˜๋ฉฐ, ๋…ธ๋ž˜๋ฅผ ์ˆ˜๋กํ•˜๋Š” ๊ธฐ์ค€์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
1. ์†ํ•œ ๋…ธ๋ž˜๊ฐ€ ๋งŽ์ด ์žฌ์ƒ๋œ ์žฅ๋ฅด๋ฅผ ๋จผ์ € ์ˆ˜๋กํ•ฉ๋‹ˆ๋‹ค.
2. ์žฅ๋ฅด ๋‚ด์—์„œ ๋งŽ์ด ์žฌ์ƒ๋œ ๋…ธ๋ž˜๋ฅผ ๋จผ์ € ์ˆ˜๋กํ•ฉ๋‹ˆ๋‹ค.
3. ์žฅ๋ฅด ๋‚ด์—์„œ ์žฌ์ƒ ํšŸ์ˆ˜๊ฐ€ ๊ฐ™์€ ๋…ธ๋ž˜ ์ค‘์—์„œ๋Š” ๊ณ ์œ  ๋ฒˆํ˜ธ๊ฐ€ ๋‚ฎ์€ ๋…ธ๋ž˜๋ฅผ ๋จผ์ € ์ˆ˜๋กํ•ฉ๋‹ˆ๋‹ค.
๋…ธ๋ž˜์˜ ์žฅ๋ฅด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฌธ์ž์—ด ๋ฐฐ์—ด genres์™€ ๋…ธ๋ž˜๋ณ„ ์žฌ์ƒ ํšŸ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ •์ˆ˜ ๋ฐฐ์—ด plays๊ฐ€ ์ฃผ์–ด์งˆ ๋•Œ, ๋ฒ ์ŠคํŠธ ์•จ๋ฒ”์— ๋“ค์–ด๊ฐˆ ๋…ธ๋ž˜์˜ ๊ณ ์œ  ๋ฒˆํ˜ธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ return ํ•˜๋„๋ก solution ํ•จ์ˆ˜๋ฅผ ์™„์„ฑํ•˜์„ธ์š”.

์ œํ•œ ์‚ฌํ•ญ

genres[i]๋Š” ๊ณ ์œ ๋ฒˆํ˜ธ๊ฐ€ i์ธ ๋…ธ๋ž˜์˜ ์žฅ๋ฅด์ž…๋‹ˆ๋‹ค.
plays[i]๋Š” ๊ณ ์œ ๋ฒˆํ˜ธ๊ฐ€ i์ธ ๋…ธ๋ž˜๊ฐ€ ์žฌ์ƒ๋œ ํšŸ์ˆ˜์ž…๋‹ˆ๋‹ค.
genres์™€ plays์˜ ๊ธธ์ด๋Š” ๊ฐ™์œผ๋ฉฐ, ์ด๋Š” 1 ์ด์ƒ 10,000 ์ดํ•˜์ž…๋‹ˆ๋‹ค.
์žฅ๋ฅด ์ข…๋ฅ˜๋Š” 100๊ฐœ ๋ฏธ๋งŒ์ž…๋‹ˆ๋‹ค.
์žฅ๋ฅด์— ์†ํ•œ ๊ณก์ด ํ•˜๋‚˜๋ผ๋ฉด, ํ•˜๋‚˜์˜ ๊ณก๋งŒ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
๋ชจ๋“  ์žฅ๋ฅด๋Š” ์žฌ์ƒ๋œ ํšŸ์ˆ˜๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

์ž…์ถœ๋ ฅ ์˜ˆ

genres plays return
["classic", "pop", "classic", "classic", "pop"] [500, 600, 150, 800, 2500] [4, 1, 3, 0]

https://school.programmers.co.kr/learn/courses/30/lessons/42579?language=java 

 

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

์ฝ”๋“œ ์ค‘์‹ฌ์˜ ๊ฐœ๋ฐœ์ž ์ฑ„์šฉ. ์Šคํƒ ๊ธฐ๋ฐ˜์˜ ํฌ์ง€์…˜ ๋งค์นญ. ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค์˜ ๊ฐœ๋ฐœ์ž ๋งž์ถคํ˜• ํ”„๋กœํ•„์„ ๋“ฑ๋กํ•˜๊ณ , ๋‚˜์™€ ๊ธฐ์ˆ  ๊ถํ•ฉ์ด ์ž˜ ๋งž๋Š” ๊ธฐ์—…๋“ค์„ ๋งค์นญ ๋ฐ›์œผ์„ธ์š”.

programmers.co.kr

 

๐Ÿ’ก ๋ฌธ์ œ ํ’€์ด

์žฌ๋ฐŒ๋Š” ๋ฌธ์ œ์˜€๋‹ค! ์ผ๋‹จ ๋ฌธ์ œ ์„ค๋ช…๋งŒ ์ฝ์–ด๋ดค์„ ๋•Œ๋Š” ์‰ฝ๊ฒŒ ํ’€ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ๋ง‰์ƒ ํ’€์–ด๋ณด๋‹ˆ ์ƒ๊ฐํ•ด์•ผ ํ•  ์กฐ๊ฑด์ด ๋ช‡ ์žˆ์—ˆ๋‹ค. ์ด ๋ฌธ์ œ์—์„œ๋Š” Class์™€ ์ •๋ ฌ ์กฐ๊ฑด, ๊ทธ๋ฆฌ๊ณ  Hash๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

๋จผ์ € ์ •๋ ฌ ์กฐ๊ฑด์— ๋งž์ถฐ์„œ Class์™€ compareTo ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” Song ์ด๋ฆ„์˜ Class๋ฅผ ์ •์˜ํ–ˆ๊ณ , Comparable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

    static Map<String, Integer> genreTotalPlay;
    
    static class Song implements Comparable<Song> {
        int id;
        String genre;
        int playCnt;
        
        Song(int id, String genre, int playCnt) {
            this.id = id;
            this.genre = genre;
            this.playCnt = playCnt;
        }
        
        @Override
        public int compareTo(Song o) {
            if (genreTotalPlay.get(this.genre) == genreTotalPlay.get(o.genre)) {
                if (this.playCnt == o.playCnt) {
                    return this.id - o.id;
                }
                return o.playCnt - this.playCnt;
            }
            return genreTotalPlay.get(o.genre) - genreTotalPlay.get(this.genre);
        }
        
    }

์—ฌ๊ธฐ์„œ genreTotalPlay๋Š” ์žฅ๋ฅด์˜ ์ „์ฒด ์žฌ์ƒ ์ˆ˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ๋Š” HashMap ๋ณ€์ˆ˜์ด๋‹ค.

์ •๋ ฌ ์กฐ๊ฑด์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

์ „์—ญ Map ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ, ์žฅ๋ฅด์˜ ์ „์ฒด ์žฌ์ƒ ์ˆ˜(genreTotalPlay.get(Song.genre))๋ฅผ ๋จผ์ € ๋น„๊ตํ•ด์„œ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌํ•œ๋‹ค.

์žฅ๋ฅด(์žฅ๋ฅด์˜ ์ „์ฒด ์žฌ์ƒ ์ˆ˜)๊ฐ€ ๊ฐ™๋‹ค๋ฉด, ๋…ธ๋ž˜์˜ ์žฌ์ƒ ์ˆ˜(Song.playCnt)๋ฅผ ๋น„๊ตํ•ด์„œ ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌํ•œ๋‹ค.

๋…ธ๋ž˜์˜ ์žฌ์ƒ ์ˆ˜๋„ ๊ฐ™๋‹ค๋ฉด, ๊ณ ์œ  ๋ฒˆํ˜ธ(id)๋ฅผ ๋น„๊ตํ•ด์„œ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌํ•œ๋‹ค.

 

ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ–ˆ์œผ๋ฉด, ์ด์ œ ์žฅ๋ฅด ์ „์ฒด ์žฌ์ƒ ์ˆ˜๋ฅผ ์ „์—ญ Hash ๋ณ€์ˆ˜์— ์ €์žฅํ•ด์ฃผ๊ณ , ๊ฐ ๋…ธ๋ž˜๋ฅผ ๋ฆฌ์ŠคํŠธ ์ €์žฅ ๋ฐ ์ •๋ ฌํ•ด์ค€๋‹ค.

        genreTotalPlay = new HashMap<>(); // ์žฅ๋ฅด ์ „์ฒด ์žฌ์ƒ ์ˆ˜(์ „์—ญ ๋ณ€์ˆ˜)
        List<Song> songs = new ArrayList<>(); // ๋…ธ๋ž˜ ์ •๋ณด ๋ฆฌ์ŠคํŠธ
        
        for (int i = 0; i < genres.length; i++) {
            if (!genreTotalPlay.containsKey(genres[i])) genreTotalPlay.put(genres[i], 0);
            genreTotalPlay.put(genres[i], genreTotalPlay.get(genres[i]) + plays[i]);
            songs.add(new Song(i, genres[i], plays[i]));
        }
        
        Collections.sort(songs);

genres์™€ plays ๋ฐฐ์—ด์„ ๋Œ๋ฉด์„œ "์žฅ๋ฅด ์ „์ฒด ์žฌ์ƒ ์ˆ˜(genreTotalPlay)"์™€ "๋…ธ๋ž˜ ์ •๋ณด ๋ฆฌ์ŠคํŠธ(songs)" ๋ณ€์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ด์ค€๋‹ค.

๋ฐ˜๋ณต๋ฌธ ์ข…๋ฃŒ ํ›„, ๋ฆฌ์ŠคํŠธ๋ฅผ ์ •๋ ฌํ•˜๋ฉด ์œ„์—์„œ ์žฌ์ •์˜ํ•œ ์ •๋ ฌ ์กฐ๊ฑด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •๋ ฌ๋œ๋‹ค.

 

๋งˆ์ง€๋ง‰ ๋‚จ์€ ๋ฌธ์ œ์˜ ์กฐ๊ฑด์ด ์žˆ๋‹ค. "๊ฐ™์€ ์žฅ๋ฅด์—์„œ ์ตœ๋Œ€ 2๊ฐœ์˜ ๋…ธ๋ž˜๋งŒ ์ˆ˜๋กํ•œ๋‹ค"๋Š” ์กฐ๊ฑด์ด๋‹ค. ์ด ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๊ธฐ ์œ„ํ•ด์„œ ์œ„์—์„œ ์ €์žฅํ•œ songs ๋ฆฌ์ŠคํŠธ์—์„œ ๊ฐ™์€ ์žฅ๋ฅด์˜ ์ตœ๋Œ€ 2๊ฐœ์˜ ๋…ธ๋ž˜๋งŒ ๋‚จ์•„์žˆ๋„๋ก ํ•„ํ„ฐ๋งํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ด ๋˜ํ•œ HashMap ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ, ๊ฐ™์€ ์žฅ๋ฅด์— ๋Œ€ํ•ด์„œ 3๋ฒˆ์งธ ๋…ธ๋ž˜๋ถ€ํ„ฐ๋Š” ๊ฑธ๋Ÿฌ์ฃผ๋ฉด ๋œ๋‹ค.

        Map<String, Integer> genreCount = new HashMap<>();
        List<Integer> album = new ArrayList<>();
        
        for (Song song : songs) {
            if (!genreCount.containsKey(song.genre)) genreCount.put(song.genre, 0);
            if (genreCount.get(song.genre) >= 2) continue;
            genreCount.put(song.genre, genreCount.get(song.genre) + 1);
            album.add(song.id);
        }

genreCount ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•ด์„œ ๊ฐ™์€ ์žฅ๋ฅด์— ๋Œ€ํ•ด ์„ ๋‘์— ์žˆ๋Š” ์ตœ๋Œ€ 2๊ฐœ์˜ ๋…ธ๋ž˜๋งŒ album ๋ฆฌ์ŠคํŠธ์— ์ €์žฅํ•ด์ค€๋‹ค. ์ด๋ฏธ ์•ž์—์„œ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ •๋ ฌํ–ˆ์œผ๋ฏ€๋กœ ์ˆœ์„œ๋Œ€๋กœ ํŒ๋‹จํ•˜๋ฉด ๋œ๋‹ค.

 

์œ„ ํ’€์ด ๋ฐฉ๋ฒ•์„ ์ „์ฒด ์ฝ”๋“œ๋กœ ํ’€์–ด๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

import java.util.*;

class Solution {
    
    static Map<String, Integer> genreTotalPlay;
    
    static class Song implements Comparable<Song> {
        int id;
        String genre;
        int playCnt;
        
        Song(int id, String genre, int playCnt) {
            this.id = id;
            this.genre = genre;
            this.playCnt = playCnt;
        }
        
        @Override
        public int compareTo(Song o) {
            if (genreTotalPlay.get(this.genre) == genreTotalPlay.get(o.genre)) {
                if (this.playCnt == o.playCnt) {
                    return this.id - o.id;
                }
                return o.playCnt - this.playCnt;
            }
            return genreTotalPlay.get(o.genre) - genreTotalPlay.get(this.genre);
        }
        
    }
    
    public int[] solution(String[] genres, int[] plays) {
        // ์žฅ๋ฅด์˜ ์ „์ฒด ์žฌ์ƒ ์ˆ˜ ๊ตฌํ•˜๊ธฐ & ๋…ธ๋ž˜ ์ˆœ์„œ ์ •๋ ฌํ•˜๊ธฐ
        genreTotalPlay = new HashMap<>();
        List<Song> songs = new ArrayList<>();
        
        for (int i = 0; i < genres.length; i++) {
            if (!genreTotalPlay.containsKey(genres[i])) genreTotalPlay.put(genres[i], 0);
            genreTotalPlay.put(genres[i], genreTotalPlay.get(genres[i]) + plays[i]);
            songs.add(new Song(i, genres[i], plays[i]));
        }
        
        Collections.sort(songs);
        
        // ๊ฐ™์€ ์žฅ๋ฅด ์ตœ๋Œ€ 2๊ฐœ๊นŒ์ง€๋งŒ ๋…ธ๋ž˜ ์ˆ˜๋กํ•˜๊ธฐ
        Map<String, Integer> genreCount = new HashMap<>();
        List<Integer> album = new ArrayList<>();
        
        for (Song song : songs) {
            if (!genreCount.containsKey(song.genre)) genreCount.put(song.genre, 0);
            if (genreCount.get(song.genre) >= 2) continue;
            genreCount.put(song.genre, genreCount.get(song.genre) + 1);
            album.add(song.id);
        }
        
        // ArrayList to Array ๋ณ€ํ™˜
        int[] answer = new int[album.size()];
        for (int i = 0; i < album.size(); i++) {
            answer[i] = album.get(i);
        }
        
        return answer;
    }
}

 

โœจ ํฌ์ŠคํŒ…์„ ๋งˆ์น˜๋ฉฐ

ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•ด์„œ ์ •๋ ฌ ์กฐ๊ฑด์„ ์žฌ์ •์˜ํ•˜๊ณ , ๋‹ต์„ ๋„์ถœํ•ด๋‚ด๋Š” ๊ณผ์ •์ด ์žฌ๋ฐŒ์—ˆ๋‹ค. ์–ธ์ œ๋ถ€ํ„ด๊ฐ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ์—์„œ๋„ ํด๋ž˜์Šค ์ •์˜๋ฅผ ์ ๊ทน ํ™œ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ๊ฐ€๋…์„ฑ๋„ ์ข‹์•„์ง€๊ณ  ํ™œ์šฉ๋„๋„ ์ข‹์€ ๊ฒƒ ๊ฐ™๋‹ค. ๐Ÿ‘

๋ฐ˜์‘ํ˜•
LIST