728x90
코딩테스트 연습 / 해시 / 베스트앨범
📀 베스트앨범
🏷️ 관련 주제 : 해시
HashMap
정렬
💡 Solution With HashMap & 정렬
import java.util.HashMap;
import java.util.ArrayList;
import java.util.stream.IntStream;
class Solution {
public int[] solution(String[] genres, int[] plays) {
int[] answer = {};
int total_songs = genres.length;
HashMap<String, Integer> total_plays_of_song = new HashMap<>();
HashMap<String, Integer> genre_song_count = new HashMap<>();
IntStream.range(0, total_songs).forEach(i -> {
String genre = genres[i];
Integer play = plays[i];
if (total_plays_of_song.containsKey(genre)) {
Integer total_plays = total_plays_of_song.get(genre);
total_plays_of_song.put(genre, total_plays + play);
return;
}
total_plays_of_song.put(genre, play);
});
ArrayList<Integer> songList = new ArrayList<>();
IntStream.range(0, total_songs)
.boxed()
.sorted((x, y) -> {
String genreX = genres[x];
String genreY = genres[y];
if (!genreX.equals(genreY)) {
return total_plays_of_song.get(genreY) - total_plays_of_song.get(genreX);
}
return plays[y] - plays[x];
})
.forEachOrdered(x -> {
String genreX = genres[x];
if (genre_song_count.containsKey(genreX)) {
Integer song_cnt = genre_song_count.get(genreX);
if (song_cnt == 1) {
genre_song_count.put(genreX, song_cnt + 1);
songList.add(x);
}
return;
}
genre_song_count.put(genreX, 1);
songList.add(x);
});
answer = songList.stream()
.mapToInt(i -> i)
.toArray();
return answer;
}
}
📗 참고 자료
- [Java] 자바 - HashMap 사용방법 (개념, 특징, 메소드 및 예제)
- Converting HashMap Values to an ArrayList in Java
- [Java] 배열을 List로, List를 배열로 변환하기
- [Stream] Java Stream 정렬(sort) 사용법(sorted)(1)
- [ JAVA ] JAVA IntStream 주요 메서드 정리
- Object.equals()와 equals() 의 차이
- Java에서 내림차순으로 IntStream 생성
- [Java/자바] IntStream을 List로 변환하는 방법
- [Java] Integer ArrayList을 int 배열로 변환 방법
- 14-40~44 스트림의 최종연산
- [JAVA] 혼동하기 쉬운 Objects.equals의 null 처리
🖋️ 풀이 과정
처음 문제를 풀 때, 가장 많이 재생된 노래를 "2개씩" 모은다는 조건을 빼 먹어서 문제가 왜 이렇게 쉽지?
라고 생각했는데 나중에서야 그 조건을 보고 코드를 다시 작성해야했다.
문제를 찬찬히 읽고, 주석 작성하기!
실천이 잘 안되는데 내일부터는 꼭 해 보아야겠다.
문제 유형에 해시라고 되어 있어서 HashMap으로 문제를 해결하였다.
- 키(Key): 장르
- 값(Value): 총 재생 횟수
1. 각 장르별 재생 횟수를 모두 더하기
int total_songs = genres.length;
HashMap<String, Integer> total_plays_of_song = new HashMap<>();
IntStream.range(0, total_songs).forEach(i -> {
String genre = genres[i];
Integer play = plays[i];
if (total_plays_of_song.containsKey(genre)) {
Integer total_plays = total_plays_of_song.get(genre);
total_plays_of_song.put(genre, total_plays + play);
return;
}
total_plays_of_song.put(genre, play);
});
2. 정렬 및 2번째 이후 순위의 곡을 제외
int total_songs = genres.length;
HashMap<String, Integer> genre_song_count = new HashMap<>();
IntStream.range(0, total_songs)
.boxed()
.sorted((x, y) -> {
String genreX = genres[x];
String genreY = genres[y];
if (!genreX.equals(genreY)) {
return total_plays_of_song.get(genreY) - total_plays_of_song.get(genreX);
}
return plays[y] - plays[x];
})
.forEachOrdered(x -> {
String genreX = genres[x];
if (genre_song_count.containsKey(genreX)) {
Integer song_cnt = genre_song_count.get(genreX);
if (song_cnt == 1) {
genre_song_count.put(genreX, song_cnt + 1);
songList.add(x);
}
return;
}
genre_song_count.put(genreX, 1);
songList.add(x);
});
좀 더 구체적으로는
2-1. 정렬
두 곡을 서로 비교하여 서로 다른 장르이면 장르별 총 재생 횟수 기준 내림차순 정렬을 적용하였다.
장르 비교는 Objects.equals()를 사용할지, 그냥 equals()를 사용할 지 고민하다가
장르가 null이 나오는 경우가 없어서 그냥 equals()로 비교해 주었다.
if (!genreX.equals(genreY)) {
return total_plays_of_song.get(genreY) - total_plays_of_song.get(genreX);
}
서로 같은 장르이면 각 노래의 재생 횟수를 기준으로 내림차순 정렬을 적용하였다.
return plays[y] - plays[x];
2-2. 각 장르별 2곡만 선정
병렬 스트림을 사용하지 않아서 forEach()문을 써도 되는데
인터넷 검색 결과로는 직렬 스트림에서 forEach()와 forEachOrdered()가 동일하다고 하는데
결과는 forEachOrdered()가 더 빨라서 forEachOrdered()를 사용하였다.
각 인덱스의 노래를 songList에 추가할 때마다 HashMap에서 장르별로 숫자를 세서
해당 장르의 노래가 이미 2곡 추가되어 있으면 songList에 곡이 추가되지 않도록 하였다.
HashMap<String, Integer> genre_song_count = new HashMap<>();
ArrayList<Integer> songList = new ArrayList<>();
// 코드 생략
.forEachOrdered(x -> {
String genreX = genres[x];
if (genre_song_count.containsKey(genreX)) { // HashMap에 해당 장르가 있는 경우
Integer song_cnt = genre_song_count.get(genreX);
if (song_cnt == 1) { // songList에 추가된 곡이 1곡인 경우, 현재 곡을 songList에 추가
genre_song_count.put(genreX, song_cnt + 1);
songList.add(x);
}
return; // songList에 추가된 곡이 2곡 이상인 경우, 현재 곡을 추가X
}
genre_song_count.put(genreX, 1); // HashMap에 해당 장르가 없는 경우
songList.add(x);
});
3. songList를 int[]로 변환하여 반환
int[] answer = {};
answer = songList.stream()
.mapToInt(i -> i)
.toArray();
return answer;
728x90