문제 해석
- 첫번째 줄에 듣도 못한 사람의 수(N)과 보도 못한 사람의 수(M)을 입력받는다.
- 처음에는 N번 듣도 못한 사람의 이름을 입력받는다.
- 그 다음줄부터는 M번 보도 못한 사람의 이름을 입력받는다.
- 다 입력 받았다면, 듣도보도못한 사람의 수와 듣도 보도 못한 사람의 이름을 출력하면 된다.
- 단, 사전순으로 출력하며, 한줄씩 출력한다.
틀린 코드
import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
String[] dArray = new String[N];
for(int i = 0; i < N; i++){
dArray[i] = br.readLine();
}
Arrays.sort(dArray);
int count = 0;
for(int i = 0; i < M; i++){
String str = br.readLine();
for(int j = 0; j < N; j++){
if(dArray[j].equals(str)){
count++;
bw.write(dArray[j] + "\n");
}
}
}
br.close();
System.out.println(count);
bw.flush();
bw.close();
}
}
틀린 결과
- 시간 초과가 나올 걸 예상했다. (근데도 이렇게 밖에 못푸는..)
코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
HashSet<String> set = new HashSet<String>();
for(int i = 0; i < N; i++) {
set.add(br.readLine());
}
List<String> outSet = new ArrayList<>();
for(int i = 0; i < M; i++){
String str = br.readLine();
if(set.contains(str)){
outSet.add(str);
}
}
Collections.sort(outSet);
bw.write(outSet.size() +"\n");
for(String str : outSet){
bw.write(str + "\n");
}
br.close();
bw.flush();
bw.close();
}
}
- 코드에 대한 설명은 주석으로 작성해두었기 때문에 생략하겠다.
정리한 내용은 아래와 같다.
- 내가 처음에 시간초과로 틀린 이유는, 배열을 썼기 때문이다.
- HashSet의 contain은 O(1)로 ArrayList의 contain는 O(n)로 시간차이가 많이 난다.
- 비록 틀린 코드에서 contain이라는 함수는 사용하지 않았지만, 사용하지 않았을 뿐 conation의 함수와 유사한 패턴이었다. => 모두 비교해서 2중 for문을 돌렸기 때문
- 또, HashSet은 map기반으로 구현되고, ArratList은 indexOf()를 사용하여 contain 여부를 결정한다.
- 이 차이로 시간 차이가 나는 것이다.
- indexOf() : (object) 메서드는 전체 배열을 반복하고 각 요소를 equals(object) 메서드와 비교
- HashSet-map기반 : 실제로 객체의 위치를 찾기 위해 hashCode() 메서드를 사용, 개체의 버킷 위치를 가져오는 것은 일정한 시간으로 수행한다.
결과
느낀 점
- hashSet이나 ArrayList나 그 밖에 다른 것들도 아직 시간에 관해서 조절하고 아끼는 방법에 익숙하지 않은 것 같고, 개념 자체도 정리되지 않아서 틀릴 수 밖에 없었던 것 같다.
- 추후에 관련 시간 복잡도를 공부하고 정리하는 시간을 가져야할 것 같다.