코딩테스트

[DFS/BFS] 타겟 넘버

Patti Smith 2024. 3. 20.
문제 설명


n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.

-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.

 

제한사항

 

주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
각 숫자는 1 이상 50 이하인 자연수입니다.
타겟 넘버는 1 이상 1000 이하인 자연수입니다.

 

사실 DFS!라기 보다는 재귀함수의 개념을 생각하며 푼 문제였다. 주어진 숫자를 기준으로 picked 배열에 뽑을 수 있는 두 가지 경우를 생각해서 자기 함수를 불러오며 뽑을 만큼 뽑았을 때 그 합을 target과 비교하는 것이다. 

 

#include <string>
#include <vector>
#include <iostream>

using namespace std;

int pick(int n, int k, vector<int> numbers, int* picked, int target){
    int cnt = 0;
    
    if(k == n){
        for(int i = 0; i < n; i++){
            cnt += picked[i];
        }
        if(cnt == target) return 1;
        else return 0;
    }
    
    if(k + 1 > n) return 0;
    
    // 더하는 경우
    picked[k] = numbers[k]; // +1
    cnt += pick(n, k + 1, numbers, picked, target);
    
    // 빼는 경우
    picked[k] = numbers[k] * -1; // -1
    cnt += pick(n, k + 1, numbers, picked, target);
    
    return cnt;
}

int solution(vector<int> numbers, int target) {
    int answer = 0;
    
    int size = numbers.size();
    
    int* picked = new int[size];
    answer += pick(size, 0, numbers, picked, target);

    return answer;
}

 

하지만 굳이 picked를 쓰지 않고 매개변수에 sum을 넣어 매 시도마다 매개변수로 sum을 가져가서 확인하는 방법도 있다. 다음처럼 코드를 작성하면 훨씬 간단해진다.

#include <string>
#include <vector>
#include <iostream>

using namespace std;

int dfs(int n, int k, vector<int> numbers, int sum, int target){
    int cnt = 0;
    
    if(k == n){
        if(sum == target)
            return 1;
        
        return 0;
    }
    
    // 더하는 경우
    cnt += dfs(n, k + 1, numbers, sum + numbers[k], target);
    
    // 빼는 경우
    cnt += dfs(n, k + 1, numbers, sum - numbers[k], target);
    
    return cnt;
}

int solution(vector<int> numbers, int target) {
    int answer = 0;
    
    int size = numbers.size();
    answer = dfs(size, 0, numbers, 0, target);

    return answer;
}

 

'코딩테스트' 카테고리의 다른 글

[SQL] 평균 일일 대여 요금 구하기  (0) 2024.03.20
[SQL] 흉부외과 또는 일반외과 의사 목록 출력하기  (0) 2024.03.20
[1758] 알바생 경호  (0) 2024.02.22
[11508] 2 + 1세일  (0) 2024.02.22
[18121] 문자열 압축  (0) 2024.02.22

댓글