본문 바로가기

Study/Programmers

프로그래머스 - 타겟 넘버

코드

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
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
int solution(vector<int> numbers, int target) {
    int answer = 0;
    vector<bool> oper(numbers.size(), false);
    int len = numbers.size();
    sort(numbers.begin(), numbers.end());
    for(int i=0; i<=len; i++)
    {
        std::fill(oper.begin(), oper.end(), false);
        std::fill(oper.end() - i, oper.end(), true); //false -> (-)
        do{
                int num = 0;
                for(int i=0; i<numbers.size(); i++)
                {
                    int minus = (!oper[i]) ? -1 : 1;
                    num += (numbers[i] * minus);
                }
                if (target == num)
                    answer++;
        }while(next_permutation(oper.begin(), oper.end()));
    }
    return answer;
}
cs

위와 같이 next_permutation으로 풀어도 되지만 사실은 재귀로 풀면 훨씬 깔끔하게 풀 수 있다.

재귀로 푼 코드
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
#include <string>
#include <vector>
 
using namespace std;
 
int total;
 
void DFS(vector<int> &numbers, int &target,int sum,int n) {
    if(n >= numbers.size()){
        if(sum == target) total++;
        return;
    }
 
    DFS(numbers, target, sum + numbers[n], n+1);
    DFS(numbers, target, sum - numbers[n], n+1);
}
 
int solution(vector<int> numbers, int target) {
    int answer = 0;
 
    DFS(numbers, target, numbers[0] , 1);
    DFS(numbers, target, -numbers[0], 1);
 
    answer = total;
 
    return answer;
}
cs

가장 처음 숫자에 대해 +로 시작하는 경우, -로 시작하는 경우를 각각 호출하여 재귀함수 내에서도 다음 숫자를 더했을 때와 뺐을 때의 경우를 재귀적으로 호출해서 현재 합계와 타겟이 같다면 count를 하는 방식이다.

재귀로 깔끔하게 푸는 연습을 하자!

'Study > Programmers' 카테고리의 다른 글

프로그래머스 - 섬 연결하기  (0) 2021.04.14
프로그래머스 - 여행 경로  (0) 2021.04.14
프로그래머스 - 단어 변환  (0) 2021.04.13
프로그래머스 - 소수 찾기  (0) 2021.04.13
프로그래머스 - 가장 큰 수  (0) 2021.04.13