소수 찾기
문제정의
숫자 카드가 주어지고, 각 숫자 카드를 조합하여 나온 숫자 중 소수가 몇 개 있는지 계산하는 문제이다.
문제풀이
전체 코드는 다음과 같다. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49import java.util.*;
public class FindPrimeNum
{
//프로그래머스 문제풀이 level2 소수 찾기
public static void main(String[] args) {
String numbers = "17";
Set<Integer> set = new HashSet<Integer>();
StringBuilder buff = new StringBuilder();
buff.append(numbers);
for(int i = 1; i <= numbers.length(); i++)
{
findKDigitPrimeNum("", 0, set, i, buff);
}
System.out.println(set.size());
}
public static void findKDigitPrimeNum(String s, int size, Set<Integer> set, int k, StringBuilder buff)
{
if(size == k)
{
int n = Integer.parseInt(s);
if(n <= 1)
return;
for(int i = 2; i <= Math.sqrt(n); i++)
{
if(n%i == 0)
return;
}
set.add(n);
}
else
{
for(int i = 0; i < buff.length(); i++)
{
StringBuilder str = new StringBuilder();
char c = buff.charAt(i);
str.append(s);
str.append(c);
findKDigitPrimeNum(str.toString(), size+1, set, k, buff.delete(i, i+1));
str.delete(str.length()-1, str.length());
buff.insert(i, c);
}
}
}
}
위 과정을 코드로 담은 것이 위에 코드다 여기서 1번 함수에 대한 세부설명을 하겠다. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30public static void findKDigitPrimeNum(String s, int size, Set<Integer> set, int k, StringBuilder buff)
{
if(size == k)
{
int n = Integer.parseInt(s);
if(n <= 1)
return;
for(int i = 2; i <= Math.sqrt(n); i++)
{
if(n%i == 0)
return;
}
set.add(n);
}
else
{
for(int i = 0; i < buff.length(); i++)
{
StringBuilder str = new StringBuilder();
char c = buff.charAt(i);
str.append(s);
str.append(c);
findKDigitPrimeNum(str.toString(), size+1, set, k, buff.delete(i, i+1));
str.delete(str.length()-1, str.length());
buff.insert(i, c);
}
}
}
시간복잡도는 문자열의 길이를 n이라 할 때, \(O(n^{n+1})\)이다.
테스트
완전 탐색이라 시간복잡도차 최악을 도는 것을 볼 수 있다. 이러한 문제는 보통 테스트 케이스의 수가 상대적으로 작다. 이런 문제가 나올 땐 효율성에 겁내지 말고 일단 해보는 것이 중요하다.