[Java] 백준 1269번: 대칭 차집합

hansung's·2024년 3월 14일
0

문제 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 이외 이진탐색도 어렵지만 해보면서 연습을 해보겠다.

profile
ABAPER를 꿈꾸는 개발자

0개의 댓글