DEV/알고리즘

[프로그래머스 Lv.1] 소수 찾기 Java

Imvory 2020. 7. 28. 11:39

문제설명

1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요.

소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다.
(1은 소수가 아닙니다.)

 

제한조건

  • n은 2이상 1000000이하의 자연수입니다.

 

입출력 예

n result
10 4
5 3

 

입출력 예 설명

입출력 예 #1
1부터 10 사이의 소수는 [2,3,5,7] 4개가 존재하므로 4를 반환

입출력 예 #2
1부터 5 사이의 소수는 [2,3,5] 3개가 존재하므로 3를 반환

 

Solution 1 - 효율성 낮음. 시간초과로 통과 X

//숫자를 2부터 자기자신까지  나누어보기
//나누어떨어지면 소수가 아님.
class Solution {
    public int solution(int n) {
        int sosu = 2; //1은 소수가 아니므로 2부터
        int cnt = 0;
        boolean flag = true;
        
        while(sosu<=n) {
        	
        	flag = true;
        	
        	for(int i=2; i<sosu; i++) {
        		if(sosu%i==0) {
        			flag = false;
        			break;
        		}
        		continue;
        	}
        	
        	if(flag==true) {
        		//System.out.println(sosu);
        		cnt++;
        	}
        	
        	sosu++;

        }
        

        return cnt;
}

이 코드는 통과하지 못하여 에라토스테네스의 체라는 알고리즘을 사용했다.

이 알고리즘은 자기 자신을 제외한 배수들을 하나씩 제거하고 소수만 남기는 방법이다.

자세한 설명은 참고한 블로그 ↓

https://marobiana.tistory.com/91

 

[C++] 소수 구하기 최적의 알고리즘 (2) - 에라토스테네스의 체

소수 구하기 최적의 알고리즘 1편에서 (http://marobiana.tistory.com/89) 주어진 수보다 작은 수의 소수들로 나누는게 성능이 좋다고 했었는데, 그것보다 더 좋은 알고리즘을 찾아냈다.ㅋㅋ 이것보다 ��

marobiana.tistory.com

 

Solution 2 (에라토스테네스의 체)

class Solution {
    public int solution(int n) {
    	int[] arr = new int[n+1];
        int cnt = 0;
		
		//배열 초기화
		for(int i=2; i<=n; i++) {
			arr[i] = i;
		}
		
		for(int i=2; i*i<=n; i++) {
			//이미 0으로 체크된 배수는 확인 X
			if(arr[i]==0)
				continue;
			
			//i를 제외한 i의 배수들을 0으로 체크
			for(int j=i+i; j<=n; j+=i) {
				arr[j] = 0;
			}
			
		}
		
		for(int i=2; i<=n; i++) {
			if(arr[i]!=0) {
				cnt++;
				//System.out.println(arr[i]);
			}
		}
		return cnt;
	}
}