[프로그래머스] 소수 찾기

NCOOKIE·2024년 5월 27일
0

알고리즘

목록 보기
18/34

https://school.programmers.co.kr/learn/courses/30/lessons/42839

코드

import java.util.HashSet;
import java.util.Set;

public class Solution {
    static boolean[] visited;
    static char[] charArray;
    static Set<Integer> result = new HashSet<>();

    static public int solution(String numbers) {
        int answer = 0;

        charArray = numbers.toCharArray();
        visited = new boolean[charArray.length];

        for (int i = 0; i < charArray.length; i++) {
            dfs(0, i + 1, "");
        }

        for (int num : result) {
            if (isPrime(num)) {
                answer++;
            }
        }

        return answer;
    }

    static private void dfs(int depth, int digits, String num) {
        // N자리수 숫자가 완성되면 소수 판별
        if (depth == digits) {
            result.add(Integer.parseInt(num));
            return;
        }
        
        for (int i = 0; i < charArray.length; i++) {
            // 정수의 첫째 자리가 0이면 생략
            if (depth == 0 && charArray[i] == '0') {
                continue;
            }

            if (!visited[i]) {
                visited[i] = true;
                dfs(depth + 1, digits, num + charArray[i]);
                visited[i] = false;
            }
        }
    }

    // 소수 판별 함수
    static public boolean isPrime(int number) {
        // 1보다 작거나 같은 경우 소수가 아님
        if (number <= 1) {
            return false;
        }
        // 2와 3은 소수
        if (number == 2 || number == 3) {
            return true;
        }
        // 짝수이거나 3으로 나누어 떨어지면 소수가 아님
        if (number % 2 == 0 || number % 3 == 0) {
            return false;
        }
        // 5부터 루트 number까지 홀수에 대해 나눠보며 검사
        for (int i = 5; i * i <= number; i += 6) {
            if (number % i == 0 || number % (i + 2) == 0) {
                return false;
            }
        }
        return true;
    }
}

풀이

숫자 카드로 만들 수 있는 모든 경우의 수를 찾기 위해 DFS를, 결과의 중복 제거를 위해 Set 자료형을 사용했다.

나 같은 경우 자릿수 별로 숫자를 구했다. 예를 들어 입력으로 "317"이 들어왔을 때, 한 자리 숫자만 따로 구하고, 두 자리 숫자, 세 자리 숫자를 각각 구하도록 했다.

마지막에는 Set를 순회하면서 소수인 경우에만 정답에 추가되도록 했다. 원래는 재귀의 종료 조건에 다다를 때마다 소수 검사를 했었는데, 성능적으로는 크게 차이가 없었다.

profile
일단 해보자

0개의 댓글

관련 채용 정보