아마 일반적인 풀이로는 각 수마다 소수인지 아닌지 판별을 하는 나머지 계산을 하고 여기 오셨을 거라고 생각합니다. 저도 그랬거든요.
2%2 = 0 -> 소수임!
3%2=1 -> 소수 아님
4%2 = 0 -> 1과 자기 자신외의 수로 나뉘어짐 -> 소수 아님
5%2 = 1 -> 불필요한 계산1
5%3 = 1 -> 불필요한 계산2
5%4 = 1 -> 불필요한 계산3
5%5 = 0 -> 소수임!
...
라고 아마 하셨을 겁니다.
위를 보시면 불필요한 계산이 3개 있습니다.
위의 계산이 컴퓨터에서 처리 할때마다 컴퓨터는 %계산을 하게됩니다. -> 시간 증가
[에라토스테네스의 체를 통한 해결방법 정리]
https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4
만약 위 불필요한 계산을 하지않고
배열로 정리하여 모든 수들을 각 방의 번호에 대입합니다. ex)a[0] = 0, a[1] = 1, a[2] = 2 ... a[n] = n
그리고 1은 소수가 아니니 0이라고 정의해봅시다. a[1] = 0
그럼 나머지 방들은 각 방마다 자신의 번호의 수가 있을 겁니다.
조건문으로 만약 방의 값이 0이 아니라면 지속한다고 해봅시다.
2번째 방의 값은 0이 아님 -> 소수이기 때문에 2라고 두고
n범위 까지의 수 범위에서 2의 배수인 수들의 방안의 값을 0이라고 정의합니다 -> (a)
3번째 방의 값은 0이 아님 -> 소수이기 때문에 3이라고 둠
n범위 까지의 수 범위에서 3의 배수인 수들의 방안의 값을 0이라고 정의합니다 -> (b)
4는 (a)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
5번째 방의 값은 0이 아님 -> 소수이기 때문에 5이라고 둠
n범위 까지의 수 범위에서 5의 배수인 수들의 방안의 값을 0이라고 정의합니다
6은 (a),(b)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
7번째 방의 값은 0이 아님 -> 소수이기 때문에 7이라고 둠
n범위 까지의 수 범위에서 7의 배수인 수들의 방안의 값을 0이라고 정의합니다
8은 (a)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
9은 (b)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
10은 (a)에서 0이라고 정의 -> 소수가 아니라고 정의 했기 때문에 넘어갑니다. -> 계산하지 않아도 됨 -> 시간 절약
...
처럼 8,9,10에서 1부터 계산하지 않고도 소수라고 정의할 수 있습니다.
그렇게 되면 주어진 범위 내에서 모든 소수를 찾으셨을텐데
소수가 아닌 수는 0이라고 정의했기 때문에
조건문으로 배열안에 있는 수가 0이 아니라면
answer++
라고 정의해주시고 마지막에 return answer; 라고 해주시면 n의 범위에서 소수의 갯수를 모두 더한 answer값이 제출 될겁니다.
💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜
원본 코드의 출처는 deamp9312의 코드입니다.
https://programmers.co.kr/questions/19255
💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜💜
class Solution {
public int solution(int n) {
int answer = 0; // 정답 정의
int[] arr = new int[n+1]; // int타입의 arr은 n+1개의 갯수만큼 int타입으로 공간을 가짐
// 모든 수를 대입
for(int i=0;i<=n;i++){ // int타입 i; 0부터 n이하까지 반복; i++
arr[i]=i; // arr의 i번째 방은 i이다
}// 0번째 방은 =1, n-1번째 방은 =n이 된다
// 1은 소수가 아니라서 0이라고 정의 --> 0이라고 함
arr[1]=0; // arr의 1번째 방은 0
// 소수 찾기 시작
for(int i=2;i<=n;i++){//2부터 계산해줌 int타입 i는 2; i가 n이하까지 반복; i++
// 만약 이전에 찾았던 소수의 배수 값일 경우 계산없이 다음 수로 이동
if(arr[i]==0)continue; // arr[i]번째 방이 0이라면 반복문의 처음으로 이동
// 에라토스테네스의 체를 통해 배수의 수는 소수가 아니라고 정의
for(int j=i*2;j<=n;j+=i){ // int타입 j가 i*2이고; j가 n이하까지 반복; j = j+i -> 계산을 하지않고 소수가 아닌 값을 찾음
arr[j]=0; // arr의 j번째 방은 0 -> 소수가 아니라면
}
}
// 정답 계산
for(int i=0;i<arr.length;i++){ // int타입 i는 arr의 길이 미만동안 반복 i++
if(arr[i]!=0){ // arr의 i번째 방이 0이 아니라면 -> 소수
answer++; // answer++
}
}
return answer;
}
}
감사합니다