[BOJ] 1181. 단어정렬
문제
알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.
- 길이가 짧은 것부터
- 길이가 같으면 사전 순으로
https://www.acmicpc.net/problem/1181
1181번: 단어 정렬
첫째 줄에 단어의 개수 N이 주어진다. (1≤N≤20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.
www.acmicpc.net
입력
첫째 줄에 단어의 개수 N이 주어진다. (1≤N≤20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.
출력
조건에 따라 정렬하여 단어들을 출력한다. 단, 같은 단어가 여러 번 입력된 경우에는 한 번씩만 출력한다.
예제 입력
13 but i wont hesitate no more no more it cannot wait im yours
예제 출력
i im it no but more wait wont yours cannot hesitate
풀이
둘 다 ArrayList에서 collection.sort를 가지고 정렬하였다. 둘의 차이점은 중복확인을 할 때 contains를 썼느냐와 set을 썼는지의 차이이다.
확실히 set을 썼을 때 시간이 더 빨랐다.
contains가 느린 이유는 contains의 시간복잡도는 O(n)인데, 데이터를 입력받을 때 마다 확인해서 총 O(n^2)의 시간이 걸려서 더 오래 걸린 것 같다.
참고 : https://hee96-story.tistory.com/89
JAVA Collection 시간 복잡도
알고리즘 문제를 풀다가 사용한 자료구조(컬랙션)에 따라 시간이 많이 차이나는 것을 알았다. 다음은 각 컬랙션 클래스의 시간복잡도를 정리한 것이다. List Class Name Add Remove Get Contains ArrayList O(1)
hee96-story.tistory.com
Contains 함수 사용 (37780KB / 2700ms)
private void usingContains() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ArrayList<String> data = new ArrayList<>();
for (int i = 0; i < n; i++) {
String value = sc.next();
if (!data.contains(value))
data.add(value);
}
Collections.sort(data, (o1, o2) -> {
Integer v1 = o1.length();
Integer v2 = o2.length();
if (v1 == v2)
return o1.compareTo(o2);
return v1 - v2;
});
for (int i = 0; i < data.size(); i++) {
System.out.println(data.get(i));
}
}
HashSet 사용 (39488KB / 908ms)
private static void usingSet() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Set<String> setData = new HashSet<>();
for (int i = 0; i < n; i++) {
String value = sc.next();
setData.add(value);
}
ArrayList<String> data = new ArrayList<>(setData);
Collections.sort(data, (o1, o2) -> {
Integer v1 = o1.length();
Integer v2 = o2.length();
if (v1 == v2)
return o1.compareTo(o2);
return v1 - v2;
});
for (int i = 0; i < data.size(); i++) {
System.out.println(data.get(i));
}
}