Algorithm/Programmers

[Programmers] 도넛과 막대 그래프

Jyuni 2024. 1. 24. 23:33

문제 출처 : https://school.programmers.co.kr/learn/courses/30/lessons/258711

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 풀이

무관한 정점을 생성한 edges에서 무관한 정점과 도넛, 막대, 8자 모양 그래프의 개수를 구하기.


1. 무관한 정점 찾기 : 정점에 들어오는 간선 == 0 && 나가는 간선 > 1을 충족해야 함
(예시 1번)의 4번 정점과 같이 들어오는 간선은 없지만 나가는 간선이 1개인 것은 막대 그래프일 수도 있기 때문
        
2. 그래프 개수 세기 : 정점에서 나가는 간선이 없고 들어오는 간선이 1개 이상이면 막대 그래프, 나가는 간선이 2개 이상이면 8자 그래프이다. 모든 그래프는 무관한 정점과 이어져 있기 때문에 (무관한 정점에서 나가는 간선 = 도넛 + 막대 + 8자)이기 때문에 막대와 8자를 알면 도넛 그래프 개수도 구할 수 있다.

 

※ 문제에서 노드의 범위는 1_000_000이지만 혹시 몰라서 edge.length + 2까지 설정하니 시간은 줄일 수 있었다. 하지만 범위에 맞춰야 함.

코드

import java.util.*;

class Solution {

    int[] answer = new int[4];
    int MAX = 1_000_001;

    public int[] solution(int[][] edges) {
        // init       
        int[] inArr = new int[MAX];
        int[] outArr = new int[MAX];
        
        for(int[] edge : edges) {
            inArr[edge[1]]++;
            outArr[edge[0]]++;
        }
        
        // 무관한 정점 찾기
        answer[0] = findNode(inArr, outArr);
        
        // 그래프 모양 개수 구하기
        countGraph(inArr, outArr);
        
        answer[1] = outArr[answer[0]] - answer[2] - answer[3];
        return answer;
    }
    
    public int findNode(int[] inArr, int[] outArr) {        
        int node = 0;
        
        for(int i=1; i<MAX; i++) {
            if(inArr[i] == 0) {
                if(outArr[i] > 1) return i;
                node = i;
            } 
        }
        return node;
    }

    public void countGraph(int[] inArr, int[] outArr) {
        for(int i=1; i<MAX; i++) {
            if(i == answer[0]) continue;
            
            if(outArr[i] > 1) answer[3]++;
            else if(inArr[i] > 0 && outArr[i] == 0) answer[2]++;
        }
    } 
}