프로그래머스 | LV.2 소수 찾기 - DFS 문풀 (Java)

728x90

⬛ 프로그래머스 | LV.2 소수 찾기 - DFS 문풀

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

 

프로그래머스

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

programmers.co.kr

 

문제 설명


💚 문제 접근 방식

  • DFS로 만들 수 있는 모든 숫자 조합으로 깊이 뻗되, 1) 중복없이 뻗고 2) 만들어진 수가 소수인지 판별하는 방식으로 풀고자 했다.
  • 우선 numbers 각각의 값들로 만들 수 있는 모든 경우의 숫자를 DFS로 깊이 탐색하면서 빠짐없이 만들어야 한다. 중복없이 만들어야 하기 때문에 visited 로 방문 체크하면서 뻗어갔다.
  • 이후 만들어진 모든 숫자들 중 소수인 경우에 한해서 map에 중복 없이 담고, 결과적으로 map의 size()를 반환하면 정답이 된다.
주의할 점 1) 값을 중복사용하면 안된다.
     “17”로 만들 수 있는 모든 경우의 숫자는 1, 7, 17, 71만 있다. 11과 77은 불가능하다.
주의할 점 2) 만든 모든 숫자 중에서 소수인 경우만 카운팅한다.
      만들 수 있는 모든 숫자가 1, 7, 17, 71 이지만, 1 의 경우 소수는 아니다. 이런 경우는 제외한다. 

풀이 설명

소수 판별은 에라토스테네스의 체 방식으로 시도했다. 기본적으로 소수판별 알고리즘은 O(N) 인데 2~n-1까지 모두 검사할 필요 없이 2~N/2까지의 수만 검사하면 O(N/2) 의 시간복잡도로 문제를 해결할 수 있기 때문이다. 

💚 제출 코드

import java.util.*;

class Solution {
    static boolean[] visited;
    static Map<Integer, Integer> map = new HashMap<>();
    //isPrime
    static boolean isPrime(int val){
        if(val == 0 || val == 1) return false;
        
        for(int i=2; i<=(int) Math.sqrt(val); i++){
            if(val % i == 0) return false;
        }
        return true;
    }
    
    //DFS
    static void DFS(String tmp, String n){
        if(!tmp.equals("")) {
            int num = Integer.parseInt(tmp);
            if(isPrime(num)){
                map.put(num, map.getOrDefault(num, 0) + 1);
            }
        }
        for(int i=0; i<n.length(); i++){
            if(!visited[i]){
                visited[i] = true;
                DFS(tmp + n.charAt(i), n);
                visited[i] = false;
            }
        }
    }
    
    //solution 
    public int solution(String numbers) {
        int answer = 0;
        visited =new boolean[numbers.length()];
        DFS("", numbers);
	      
        answer = map.size();
        
        return answer;
    }
}
728x90