항해99를 하면서 풀어봤던 문제지만 다시 한 번 풀어보기
https://www.acmicpc.net/problem/10816
- 예제 입력1
10
6 3 2 10 10 10 -10 -10 7 3
8
10 9 -5 2 3 4 5 -10
- 예제 출력1
3 0 0 1 2 0 0 2
- 문제 접근
- 입력
- 첫째 줄 : 상근이가 가진 카드 개수 N (1 <= N <= 500,000)
- 둘째 줄 : 숫자 카드에 적힌 정수 (-10,000,000 <= 숫자 <= 10,000,000)
- 셋째 줄 : M (1 <= N <= 500,000)
- 넷째 줄 : 상근이가 몇 개 가지고 있는 숫자 카드인지 비교할 숫자 카드 (-10,000,000 <= 숫자 <= 10,000,000)
- 출력
- 네 번째 줄에 있는 카드를 상근이가 몇 개 가지고 있는지를 공백으로 구분하여 한 줄 출력
- 입력
- 문제 해결
- 숫자 카드 1 문제와 달라진 점은 상근이가 가진 숫자 카드(둘째 줄)이 중복되어 카운팅을 해야하는 것
- 방법1) 배열을 이용하여 둘째 줄의 숫자가 들어올 때마다 해당 숫자 index 카운트
- 방법2) Map을 이용하여 디폴트 값을 0으로 잡고, 중복된 Key값(숫자 카드)가 들어오면 Value += 1
- 방법1) 배열 풀이 [메모리 : 196,808 KB / 시간 : 824 ms]
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
int[] sangCard = new int[20000001];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i = 1; i <= N; i++){
int number = Integer.parseInt(st.nextToken());
sangCard[number + 10000000]++;
}
int M = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
for(int i = 0; i < M; i++){
int number = Integer.parseInt(st.nextToken());
sb.append(sangCard[number + 10000000]).append(" ");
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb);
}
- 방법2) HashMap 풀이 [메모리 : 199,276KB / 시간 : 1,136ms]
public static void main(String[] args) throws IOException {
Map<Integer, Integer> cardMap = new HashMap<>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
int[] sangCard = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt)
.toArray();
for(int i = 0; i < N; i++){
if(cardMap.containsKey(sangCard[i])){
cardMap.put(sangCard[i], cardMap.get(sangCard[i]) + 1);
} else {
cardMap.put(sangCard[i], 1);
}
}
int M = Integer.parseInt(br.readLine());
int[] compareCard = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt)
.toArray();
for(int i = 0; i < M; i++){
sb.append(cardMap.getOrDefault(compareCard[i], 0)).append(" ");
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb);
}
- Stream 풀이 [메모리 : 184,216 KB / 시간 : 1,032 ms]
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
br.readLine();
Map<Integer, Integer> cardMap = Arrays.stream(br.readLine().split(" "))
.map(Integer::parseInt)
.collect(Collectors.toMap(key -> key, value -> 1, Integer::sum));
br.readLine();
Arrays.stream(Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt)
.toArray())
.mapToObj(i -> cardMap.getOrDefault(i, 0))
.forEach(res -> sb.append(res).append(" "));
System.out.println(sb.toString().trim());
}
- 배열 풀이는 2,000만개의 공간을 잡아두기 때문에 메모리적으로 성능이 매우 안 좋을 거라 생각하였으나, 의외로 HashMap 풀이보다 3,000 KB 가량 더 적었으며, 속도는 더욱 빨랐음
- 배열변수[인덱스]로 바로 접근하기 때문에 시간 복잡도가 O(1)이기 때문일 것이라 생각이 됨
- stream을 사용하기가 아직 익숙치 않지만 그래도 사용하다보니 점점 감이 잡히고 가독성적인 측면에서 매우 강력하다는 게 느껴짐
'Coding Test > Step14. 집합과 맵' 카테고리의 다른 글
[Java] 7단계. 대칭 차집합 [1269번] (1) | 2024.11.03 |
---|---|
[Java] 6단계. 듣보잡 [1764번] (0) | 2024.11.03 |
[Java] 4단계. 나는야 포켓몬 마스터 이다솜 [1620번] (0) | 2024.11.02 |
[Java] 3단계. 회사에 있는 사람 [7785번] (0) | 2024.11.02 |
[Java] 2단계. 문자열 집합 [14425번] (0) | 2024.11.02 |