[Algorithm] 타겟 넘버

Jay·2021년 2월 16일
0

Algorithm

목록 보기
27/44
post-thumbnail

문제 설명

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 이하인 자연수입니다.

입출력 예

numbers [1, 1, 1, 1, 1]
target 3
return 5


접근

  1. 모든 경우를 찾기 위해 DFS를 사용한다.
  2. 양수, 음수 2가지를 고려해야 함으로 재귀호출을 한다.
  3. 재귀 호출을 하면서 idx 매개변수가 주어진 배열의 길이와 같으면 연산을 멈춘다.
  4. 그 중 합계가 target과 일치하는 경우라면 cnt++을 해준다.

Code

class Solution {
    static int answer = 0 ;
    public int solution(int[] numbers, int target) {
        dfs(numbers,target,0);
        return answer;
    }

    public static void dfs(int[] numbers, int target, int node){
        if(node==numbers.length){
            int sum = 0;
            for(int num : numbers){
                sum+=num;
            }
            if(sum==target){
                answer++;
            }
        }else{
            numbers[node]*=1;
            dfs(numbers,target,node+1);
            
            numbers[node]*=-1;
            dfs(numbers,target,node+1);
        }
            
    }
}

풀이


아주 간략하게나마 설명을 해보자면
코드에서 dfs 함수에 들어가서 node가 numbers 배열의 길이와 같지 않을 경우, numbers[node]를 1로 바꾸거나 -1로 바꾸게 된다.
위의 그림에서 빨간 선은 1로 바꾼 경우를 계~~속 따라 간 것이다!

1로 4번 바꾸다가

numbers[node]*=-1;
dfs(numbers,target,node+1);

위 코드를 만나게 되면 마지막을 -1로 바꾸게 되고 이는 위 그림에서 파란색 파란색 선을 따라가게 된다.

1로 3번 바꾸다가

numbers[node]*=-1;
dfs(numbers,target,node+1);

위 코드를 만나면 보라색 선을 따라가게 될 것이다.

DFS 글에서 봤듯 순회를 하게 되는데 이를 재귀 방식으로 구현하였다.
모든 경우를 다 따져가며 우리가 찾고자 하는 target과 값이 일치할 경우, count를 올려주는 형식이다.

복습

class Solution {
    static int answer = 0;
    public int solution(int[] numbers, int target) {
        
        dfs(numbers, 0, 0, target);
        
        return answer;
    }
    
    public static void dfs(int[] numbers, int index, int result, int target){
        if(index==numbers.length){
            if(result==target){
                answer++;
            }
        }else{  
            index++;                  
            dfs(numbers, index, result+numbers[index-1], target);//더하는 경우,
            dfs(numbers, index, result-numbers[index-1], target);//빼는 경우,              
        }        
    }
}

dfs,bfs는 주기적으로 하지 않으면 자꾸 잊게 된다.
그래서 일단 2단계 문제 부터 집었다. 이전보다 빨라진듯?👀

profile
developer

0개의 댓글