문제 url:
대칭 차집합
문제:
이번 문제는 특별히 알아볼 것 없이 예시만 잘 봐도 쉽게 이해할 수 있는 문제이다.
즉, A와 B의 각 차집합의 원소 개수를 출력으로 구하면 되는것인데.
이를 구하기 위해 A_set과 B_set 총 두개를 만들어 각각 원소를 저장해주고
해당 Set에 각 원소가 포함되지 않으면 개수를 더해가면서 풀면 쉽게 풀 수 있다.
이를 코드로 알아보면 더 쉽다
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));
StringTokenizer st = new StringTokenizer(br.readLine());
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
Set<Integer> a_set = new HashSet<>();
StringTokenizer a_token = new StringTokenizer(br.readLine());
for(int i = 0; i < A; i++) {
a_set.add(Integer.parseInt(a_token.nextToken()));
}
Set<Integer> b_set = new HashSet<>();
StringTokenizer b_token = new StringTokenizer(br.readLine());
for(int i = 0; i < B; i++) {
b_set.add(Integer.parseInt(b_token.nextToken()));
}
int res = 0;
for (int num : a_set) {
if(!b_set.contains(num)) {
res++;
}
}
for (int num : b_set) {
if(!a_set.contains(num)) {
res++;
}
}
System.out.println(res);
}
}
set.contains()는 우리 HashMap에서 즐겨썻던 containsKey(), containsValue()와 같은 기능을 담당하는 메서드이다.
해당 자료구조에 value의 존재유무를 구할 수 있는 메서드인데 이를 통해 간단히 문제를 풀 수 있었다.
import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int A = Integer.parseInt(st.nextToken());
int B = Integer.parseInt(st.nextToken());
HashSet<Integer> a_set = new HashSet<>();
StringTokenizer a_token = new StringTokenizer(br.readLine());
for(int i = 0; i < A; i++) {
a_set.add(Integer.parseInt(a_token.nextToken()));
}
HashSet<Integer> b_set = new HashSet<>();
List<Integer> minus_b = new ArrayList<>();
StringTokenizer b_token = new StringTokenizer(br.readLine());
for(int i = 0; i < B; i++) {
int token = Integer.parseInt(b_token.nextToken());
if(a_set.contains(token)) {
minus_b.add(token);
} else {
b_set.add(token);
}
}
for(int i = 0; i < minus_b.size(); i++) {
a_set.remove(minus_b.get(i));
}
System.out.println(a_set.size() + b_set.size());
}
}
처음에 풀었던 문제이다. 해당 코드는 위 코드와 로직은 비슷하지만
다른게 있다면. 직접 set에서 중복값을 제거해주며 푼 문제이다.
그래서 좀 더 직관적으로 할 수 있도록 처음 코드로 리팩토링을 한 것이다
하지만!!!... 리팩토링 하기 이전 코드가 더 시간과 메모리 측면에서 효율적이다..
리팩토링 전 -> 740ms
리팩토링 후 -> 816ms시간 측면은 어쩌면 for문이 한 개 줄었기 때문에 그럴 수 있다고 감히 추측하지만
메모리는 왜?... 불필요한 List도 줄였고 했던 것인데 해당 이유는 잘 모르겠다.※그래서 챗gpt한테 물어봤다. 그러니 아래와 같은 답변을 주었다.
요즘 집합과 맵 카테고리를 풀면서 HashMap을 이용한 문제만 풀었었는데,
이렇게 Set을 써보니 키-값쌍 구조가 필요없으면 Set이 훨씬 편하고 메모리 측면에서도 효율적인 것 같다.
그래서 이번에 Set도 같이 정리를 하고자 생각중이며, 앞으로는 Set, Map 이외 이진탐색도 어렵지만 해보면서 연습을 해보겠다.