package org.example.알고리즘.귤고르기;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
solution.solution(6, new int[]{1, 3, 2, 5, 4, 5, 2, 3});
System.out.println("================================");
solution.solution(4, new int[]{1, 3, 2, 5, 4, 5, 2, 3});
System.out.println("================================");
solution.solution(2, new int[]{1, 1, 1, 1, 2, 2, 2, 3});
}
public int solution(int k, int[] tangerine) {
int answer = 0;
Map<Integer, Long> collected = Arrays.stream(tangerine)
.boxed()
.collect(Collectors.groupingBy(x -> x, Collectors.counting()));
List<Map.Entry<Integer, Long>> collect = collected.entrySet().stream()
.sorted(Map.Entry.<Integer, Long>comparingByValue().reversed())
.collect(Collectors.toList());
while (k > 0) {
System.out.println("collect = " + collect.get(0));
long value = collect.get(0).getValue();
k -= (int) value;
answer++;
collect.remove(0);
}
return answer;
}
}
- 일단 그룹화와 정렬문제이다.
- 더 효율적으로 풀 수 있을 것 같긴한데, 굳이 좋은 그루핑, 정렬 함수가 있는데 안쓸 이유가 없다.
Arrays.stream(tangerine)
.boxed()
- 귤을 스트림화한다. 이후 귤에 자체 int 값에 대해서는 그룹핑이 불가능하기에 별도 박싱을 수행한다.
.collect(Collectors.groupingBy(x -> x, Collectors.counting()));
- 박싱된 각 값의 시간복잡도 O (n)
- 에 더하여 각 Integer 값을 내부적으로 HashMap 화를 통해 각 키값(정수) 에 대해 카운트를 수행한다.
- 각각 boxed 와 collect 는 각각 O(n) 의 시간복잡도가 아니라
- 스트림자체의 지연평가때문에 결국 O(n) 의 효율을 가지게 된다.
- 에 더하여 각 Integer 값을 내부적으로 HashMap 화를 통해 각 키값(정수) 에 대해 카운트를 수행한다.
collect = 2=2
collect = 3=2
collect = 5=2
- 이런식으로 각 값에 대해 키 - 밸류 값으로 카운트가 담긴Map 을 반환하게 된다.
collected.entrySet().stream()
- 그루핑된 해시맵에 별도 순회가 필요하다
- entrySet 을 통하여 해시맵 내부의 버킷배열을 순회한다.
- 각 버킷에 있는 연결리스트 혹은 트리 구조 ( 상황에 따라 구조가 달라짐 )
- 을 확인하여 해당 값과 버킷배열의 값을 키 : 밸류 값의 Entry 객체로 들고온다,
- entrySet 을 통하여 해시맵 내부의 버킷배열을 순회한다.
.sorted(Map.Entry.<Integer, Long>comparingByValue().reversed())
- 소팅이다.
- Entry 객체에 대해 각각 값을 valuee 를 기준으로 비교한다.
(c1, c2) -> c1.getValue().compareTo(c2.getValue());
- 내부적으로는 일반적인 Comparator ..상의 정수 반환과 동일하다.
reserved() 를 통하여 역방향으로 정렬
- 내림차순 반환으로 큰 카운트를 가진 key 가 제일 앞에 온다
- Entry 객체에 대해 각각 값을 valuee 를 기준으로 비교한다.
`while (k > 0) {
System.out.println("collect = " + collect.get(0));
long value = collect.get(0).getValue();
k -= (int) value;
answer++;
collect.remove(0);
}
- collect 첫번째 entry 를 깐다
- entry 의 value 만큼 귤갯수를 차감하며
- 종류로 하나 추가해준다
- 이후에 해당 엔트리는 제거한다. ( 시간복잡도 상수시간 )
최종 시간복잡도 O(n)
Uploaded by N2T
'자바 > 알고리즘' 카테고리의 다른 글
[프로그래머스] 합승 택시 요금 [플로이드-워셜] (0) | 2023.12.31 |
---|---|
[프로그래머스] 전력망을 둘로 나누기 (0) | 2023.12.30 |
[프로그래머스] 영어 끝말잇기 (0) | 2023.12.22 |
[알고리즘] PCCP 기출 문제 2번 Java (0) | 2023.12.19 |
[프로그래머스] Lv2. 스킬트리 (0) | 2023.12.17 |