준영이의 성장일기(FrontEnd)

프로그래머스 - 소수 찾기 본문

코테 및 알고리즘

프로그래머스 - 소수 찾기

Jay_Jung 2024. 6. 24. 12:08

<문제>

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

 

프로그래머스

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

programmers.co.kr

 

 

<문제 핵심>

1. 완전 탐색

개념: 모든 경우의 수를 시도하는 방법(if문, 반복문을 사용하며 모든 경우를 확인)

 

경우의 수가 많을 수록 실행 시간이 늘어나기 때문에 입력값의 범위가 적을 때 유용

무식하게 푼다 라는 의미 또한 가지고 있어  Brute-Force (브루트 포스) 라고도 불린다.

✅ 입력으로 주어지는 데이터(N)의 크기가 매우 작다. 

✅ 이 문제에서 소수를 구하게 될텐데 소수가 아닌 경우, 최소 하나의 약수가 존재하고 , 그 약수는 항상 n의 제곱근 이하 이므로 Math.sqrt() 메소드 사용 - 제곱근 구하는 메소드

2. DFS(깊이 우선 탐색)

개념: 그래프에서 깊은 부분을 우선적으로 탐색하는 알고리즘이다.

-> 스택 기반 자료구조를 사용한다.

 

대표적은 구현 방법으로는 다음 방법이 있다.

<깊이우선탐색(DFS) 구현 방법>

  1. 탐색 시작 노드를 스택에 삽입하고 방문 처리를 한다.
  2. 스택의 최상단 노드에 방문하지 않은 인접 노드가 있으면 그 인접 노드를 스택에 넣고 방문 처리를 한다. 방문하지 않은 인접 노드가 없으면 스택에서 최상단 노드를 꺼낸다.
  3. 2번 과정을 더 이상 수행할 수 없을 때까지 반복한다.

 

<깊이우선탐색(DFS) 알고리즘 그림 및 과정>

 

1. 0부터 시작해서 스택에 담는다.

2. 0번 노드를 뽑아서 출력 -> 인접노드인 1번 노드를 스택에 담기

3. 1번 노드를 뽑아서 출력 -> 인접노드인 2번, 3번 노드를 스택에 담기

4. 3번 노드를 뽑아서 출력 -> 인접노드인 4, 5번 노드를 스택에 담기
(2번 노드는 이미 스택에 있으므로 제외) ❗여기까지 스택에 2,4,5 순서대로 담겨져 있을 것

5. 5번 노드 뽑아서 출력 -> 인접노드 더 이상 없으므로 스택에 안 담음

6. 스택에 남은 노드인 4, 2를 출력한다.

 

<문제 풀이과정 및 순서도>

 

1.  주어진 문자열 str로부터 가능한 모든 숫자 조합을 생성하여 배열로 반환하는 getPer 함수 구현

✅ ch 배열은 각 문자 사용 여부를 추적하는데 사용. 초기값은 모두 0으로 설정.(1차원 배열)

 

const getPer = (str) => {
    const answer = [];
    const n = str.length;
    let ch = Array.from({ length: n }, () => 0);
    
    const dfs = (curStr) => {
        answer.push(+curStr);
        for (let i = 0; i < n; i++) {
            if (ch[i] === 0) {
                ch[i] = 1;
                dfs(curStr + str[i]);
                ch[i] = 0;
            }
        }
    }
    dfs('');
    answer.shift();
    return answer;
}

 

 

2. 주어진 숫자 n이 소수인지 여부를 판별 하는 isPrime 함수 구현

✅ 반복문 범위를 n의 제곱근까지만 판단하고 약수가 있으면 소수로 판단한다.

const isPrime = (n) => {
    if (n === 0 || n === 1) return false;
    for (let i = 2; i <= Math.sqrt(n); i++) {
        if (n % i === 0) {
            return false;
        }
    }
    return true;
}

 

3. getPer함수의 결과물로 반환된 배열의 중복을 제거하고 새로운 배열을 생성한 뒤 배열에서 소수인 숫자들만으로 구성되도록 필터링 한다. 그리고 필터링 한 배열의 길이를 return 해주기

function solution(numbers) {
    return [...new Set(getPer(numbers))].filter(v => isPrime(v)).length;
}

 

<전체 코드>

function solution(numbers) {
    return [...new Set(getPer(numbers))].filter(v => isPrime(v)).length;
}

const getPer = (str) => {
    const answer = [];
    const n = str.length;
    let ch = Array.from({ length: n }, () => 0);
    
    const dfs = (curStr) => {
        answer.push(+curStr);
        for (let i = 0; i < n; i++) {
            if (ch[i] === 0) {
                ch[i] = 1;
                dfs(curStr + str[i]);
                ch[i] = 0;
            }
        }
    }
    dfs('');
    answer.shift();
    return answer;
}

const isPrime = (n) => {
    if (n === 0 || n === 1) return false;
    for (let i = 2; i <= Math.sqrt(n); i++) {
        if (n % i === 0) {
            return false;
        }
    }
    return true;
}

'코테 및 알고리즘' 카테고리의 다른 글

프로그래머스 - 더 맵게  (0) 2024.06.27
백준 1436번 - 영화감독 숌  (0) 2024.06.25
프로그래머스 해시 - 의상  (0) 2024.06.23
백준 11404번 - js  (0) 2024.06.21
백준 11403번 - 경로찾기  (0) 2024.06.20