https://school.programmers.co.kr/learn/courses/30/lessons/42579
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
public int[] solution(String[] genres, int[] plays) {
int[] answer = new int[genres.length];
Map<Integer, List<Object>> hashMap = new LinkedHashMap<>();
Map<Integer, String> linkedHashMap = new LinkedHashMap<>();
for (int i = 0; i < genres.length; i++) { // 1. 먼저 인덱스 값을 key로, 그 안에 <genres, plays>를 value를 가지는 hashMap 생성
hashMap.put(i, List.of(genres[i], plays[i]));
}
for (int i = 0; i < genres.length;
i++) { // 2. plays를 key로 genres를 value로 하는 LinkedHashMap을 만들고 plays 기준으로 내림차순 정렬
linkedHashMap.put(plays[i], genres[i]);
}
linkedHashMap = linkedHashMap.entrySet().stream()
.sorted((Map.Entry.<Integer, String>comparingByKey().reversed()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
Map<String, Integer> linkedHashMap2 = new LinkedHashMap<>(); // 3. 가장 많이 들은 장르를 위한 로직
for (Integer key : linkedHashMap.keySet()) {
String genre = linkedHashMap.get(key);
linkedHashMap2.put(genre, key + linkedHashMap2.getOrDefault(genre, 0));
}
linkedHashMap2 = linkedHashMap2.entrySet().stream() // 4. 정렬해서 먼저 삽입할 장르를 인지
.sorted((Map.Entry.<String, Integer>comparingByValue().reversed()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
Map<Integer, List<Object>> sortedMap = hashMap.entrySet()// 5. 내림차순 정렬
.stream()
.sorted((a, b) -> ((Integer) b.getValue().get(1)).compareTo((Integer) a.getValue().get(1)))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
// 2개 넘지 않도록 answer 배열에 저장
Map<String, Integer> countMap = new HashMap<>();
int num = 0;
for (String genre : linkedHashMap2.keySet()) { // 장르 우선순위에 따라 삽입
for (Map.Entry<Integer, List<Object>> entry : sortedMap.entrySet()) {
int index = entry.getKey();
String currentGenre = (String) entry.getValue().get(0);
if (currentGenre.equals(genre)) {
int count = countMap.getOrDefault(currentGenre, 0);
if (count < 2) {
answer[num++] = index;
countMap.put(currentGenre, count + 1);
}
}
}
}
answer = Arrays.copyOfRange(answer, 0, num); // 배열 크기 맞추기
return answer;
}
📍포인트
1. 인덱스를 key로 하고 <genres, plays>를 value로 하는 LinkedHashMap 생성 값 삽입 형태 →
Map<Integer, List<Object>> hashMap = new LinkedHashMap<>();
2. plays를 key, genres를 value로 하는 LinkedHashMap 생성 plays 기준으로 내림차순 정렬
3. 정렬된 LinkedHashMap에서 새로운 HashMap 생성 genres를 key, plays를 value로 삽입 같은 키는 누적, 같은 키가 2번 이상 나오면 무시 → 이를 위해 countMap 사용
4. 결과값을 plays 기준으로 내림차순 정렬 → 먼저 삽입할 장르 결정
5. 1번에서 만든 hashMap을 plays 기준으로 내림차순 정렬 장르가 일치하면 인덱스를 배열에 추가 장르별 최대 2개까지만 추가
📍삽질
1. 대충 쉽겠거니 접근하다가 다뤄야하는 값이 3가지라 Map으로 어떻게 구현할지 많이 고민함. (2차원 배열도 써봄)
2. 그냥 LinkedHashMap의 정렬은 자주 해봐서 할 수 있었는데, Map<Integer, List<Object>>형태 정렬 처음 해봤음. comparTo로 처리.
3. 앞으로 LinkedHashMap 정렬은
.sorted((Map.Entry.<Integer, String>comparingByKey().reversed())) 가 아닌
.sorted(((a,b)-> b.getValue().compareTo(a.getValue()))) 형식으로 사용할 예정. (확정성 용이)
'코딩테스트' 카테고리의 다른 글
[코딩테스트(Java)] 프로그래머스 81301 숫자 문자열과 영단어 (0) | 2025.03.13 |
---|---|
[코딩테스트(Java)] 프로그래머스 77484 로또의 최고 순위와 최저 순위 (0) | 2025.03.12 |
[코딩테스트(Java)] 프로그래머스 92334 신고 결과 받기 (1) | 2025.03.11 |
[코딩테스트(Java)] 프로그래머스 72410 신규 아이디 추천 (0) | 2025.03.09 |
[코딩테스트(Java)] 프로그래머스 42889 실패율 (0) | 2025.03.08 |