프로그래머스 - 뉴스 클러스터링(카카오 기출) (java)

Mendel·2024년 5월 13일

알고리즘

목록 보기
46/85

문제 접근

이 문제의 핵심은 어떻게 가장 빠르게 두 집합 간 교집합의 갯수와 합집합의 갯수를 구하느냐이다.
이 문제에는 조건이 있다. 집합 안의 원소들은 모두 길이가 2인 영어로만 구성된 문자열이라는 것이다.
또한, 문자열 간 비교시 대소문자 관계를 신경 쓰지 않는다고 했다.
따라서, a를 A라고 생각해도 된다는 것임.

그러면, 문제가 매우 간단해진다. 어차피 길이는 2인 문자열이므로, 2차원 배열로 26*26의 공간을 만들고 해당하는 문자열의 갯수를 세주면 된다.
이후, 교집합을 구할 때는 26 x 26 번 순회를 하면서 둘 중 더 작은 갯수로, 합집합을 구할때는 둘 중 더 큰 갯수로 더해주면 된다.

문제 풀이

import java.util.*;

class Solution {
    int interCount = 0;
    int unionCount = 0;
    
    int[][] count1 = new int[26][26];
    int[][] count2 = new int[26][26];
    
    public int solution(String str1, String str2) {
        int count1Size = initCount(str1, count1);
        int count2Size = initCount(str2, count2);
        
        if (count1Size == 0 && count2Size == 0) {
            return 65536;
        }
        
        countInter(count1Size, count2Size);
        countUnion();
    
        double result = (double)interCount / unionCount;
        result*=65536;
        return (int)result;
    }
    
    int initCount(String s, int[][] count) {
        int size = 0;
        for(int i=0; i<s.length()-1; i++) {
            if(isEnglish(s.charAt(i)) && isEnglish(s.charAt(i+1)) ) {
                int x = (s.charAt(i) >= 65 && s.charAt(i) <= 90) ? s.charAt(i)-65 : s.charAt(i) -97;
                int y = (s.charAt(i+1) >= 65 && s.charAt(i+1) <= 90) ? s.charAt(i+1)-65 : s.charAt(i+1) -97;
                
                count[x][y]++;
                size++;
            }
        }
        return size;
    }
    
    void countInter(int s1Size, int s2Size) {
        if (s1Size == 0 || s2Size == 0) {
            interCount = 0;
            return;
        }
        
        for (int i = 0; i<26; i++) {
            for (int j=0; j<26; j++) {
                interCount += Math.min(count1[i][j], count2[i][j]);
            }
        }
    }
    
    void countUnion() {
        for (int i = 0; i<26; i++) {
            for (int j=0; j<26; j++) {
                unionCount+=Math.max(count1[i][j],count2[i][j]);
            }
        }
    }
    
    boolean isEnglish(char c) {
        return (c >= 'A' && c <= 'Z') || 
               (c >= 'a' && c <= 'z') ;
    }
}

profile
이것저것(안드로이드, 백엔드, AI, 인프라 등) 공부합니다

0개의 댓글