728x90
설계
- 주어진 숫자들 중 가장 많이 등장하는 숫자를 찾고, 동일한 빈도의 숫자가 여러 개 있는 경우에는 가장 작은 숫자를 출력합니다.
- 각 숫자의 등장 횟수를 저장하는 HashMap을 사용하여 숫자들의 빈도를 계산하고, 이를 기반으로 정렬하는 것입니다.
- 숫자와 빈도를 2차원 배열에 저장한 후, 빈도가 동일한 경우 숫자의 크기에 따라 오름차순으로, 빈도가 다른 경우 빈도에 따라 내림차순으로 정렬합니다.
- 그 후, 가장 첫 번째 원소(가장 많이 등장하거나 가장 작은 숫자)를 출력합니다.
구현
코드
자바(Java)
// package boj11652;
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
// Scanner sc = new Scanner(System.in);
// int N = sc.nextInt(); // 사용자로부터 숫자의 개수 N을 입력받음
// 빠른 입력
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(bf.readLine());
Map<Long, Integer> map = new HashMap<>(); // 숫자와 그 빈도를 저장할 맵 생성
// N번 반복하여 각 숫자의 빈도를 맵에 저장
for (int i = 0; i < N; i++) {
// 입력 받는 숫자는 -2^62 <= l <= 2^62 범위의 정수이므로 long을 사용해야함
// long l = sc.nextLong(); // 사용자로부터 숫자를 입력받음
long l = Long.parseLong(bf.readLine());
// 적혀있을 수 있는 수의 범위가 2^63이므로 배열로 count하기에 적절하지 않음
// -> 맵을 사용하여 숫자의 빈도를 저장
// 맵에 숫자의 빈도를 저장하거나 업데이트
map.put(l, map.getOrDefault(l, 0) + 1);
}
// sc.close();
// System.out.println(map);
// 숫자들을 저장할 집합 생성
// keySet을 통해 맵의 키(중복되지 않은 숫자)를 순회할 수 있음
Set<Long> unique = map.keySet();
// 숫자와 빈도를 저장할 2차원 배열 생성
long[][] arr = new long[unique.size()][2];
// 숫자와 빈도를 순회하는 이터레이터 생성
// 이터레이터 : next() 메서드를 통해 다음 요소를 가져올 수 있는 객체
// 배열 등에 비해 메모리를 적게 사용하며, 요소를 순회하는데 유용함
Iterator<Long> keys = unique.iterator();
Iterator<Integer> values = map.values().iterator();
// 숫자와 빈도를 배열에 저장
// map으로 한 번 정리했기 때문에 최대 N개의 row를 가지는 2행의 배열을 생성
for (int i = 0; i < map.keySet().size(); i++) {
arr[i][0] = keys.next(); // 숫자 저장
arr[i][1] = values.next(); // 빈도 저장
}
// System.out.println(Arrays.deepToString(arr));
// 배열을 정렬
// 오름차순? : 데이터가 나열되는 방향이 작은 것에서 큰 것으로 (1, 2, 3, 4, 5...)
// 내림차순? : 데이터가 나열되는 방향이 큰 것에서 작은 것으로 (5, 4, 3, 2, 1...)
// Arrays.sort 메서드를 통해 배열을 정렬할 수 있음
// - 원본에 영향을 미치고, return이 없는 in-place 정렬
Arrays.sort(arr, (a, b) -> {
// 0 : 숫자, 1 : 빈도
// 앞선 요소 a, 뒤에 있는 요소 b
// 해당 요소가 자료구조일 경우 인덱스나 메서드를 통해 하위 데이터에 접근 가능
if (a[1] == b[1]) {
// 빈도가 동일할 경우 숫자 순으로 오름차순 정렬
// Long.compare 메서드를 통해 두 숫자(long) 비교
// (Integer.compare 메서드는 int를 비교)
return Long.compare(a[0], b[0]);
// a[0]가 b[0]보다 작으면 음수, 같으면 0, 크면 양수를 반환
}
// 빈도가 다를 경우 내림차순 정렬
return Long.compare(b[1], a[1]);
// b[1]가 a[1]보다 작으면 음수, 같으면 0, 크면 양수를 반환
});
// 가장 빈도가 높은 숫자 출력
System.out.println(arr[0][0]);
}
}
파이썬 (Python)
import sys
# 빠른 입력을 위한 설정
input = lambda: sys.stdin.readline().rstrip()
# 사용자로부터 숫자의 개수 N을 입력받음
N = int(input())
# 숫자와 그 빈도를 저장할 딕셔너리 초기화
m = {}
# N번 반복하여 각 숫자의 빈도를 딕셔너리에 저장
for i in range(N):
l = int(input()) # 사용자로부터 숫자를 입력받음
# 딕셔너리에 숫자의 빈도를 저장하거나 업데이트
m[l] = m.get(l, 0) + 1
# 딕셔너리의 아이템을 빈도와 숫자를 기준으로 정렬
# 빈도가 같을 경우 숫자가 큰 순서대로 정렬
sorted_items = sorted(m.items(), key=lambda x: (x[1], -x[0]))
# 가장 많이 등장하는 숫자 출력
# 빈도가 같은 경우에는 가장 큰 숫자를 출력
print(sorted_items[-1][0])
'Problem_Solving' 카테고리의 다른 글
백준(BOJ) 1654 : 랜선 자르기 (자바, 파이썬) (0) | 2024.01.17 |
---|---|
프로그래머스 : 문자열 압축 (자바, 파이썬) (0) | 2024.01.16 |
백준(BOJ) 13251 : 조약돌 꺼내기 (자바, 파이썬) (0) | 2024.01.12 |
프로그래머스 : 하노이의 탑 (자바, 파이썬) (0) | 2024.01.12 |
백준(BOJ) 15661 : 링크와 스타트 (자바, 파이썬) (0) | 2024.01.12 |