Alogorithm

[Algorithm] 프로그래머스 - 타겟 넘버 (bfs || dfs - 너비 || 깊이 우선탐색)

Daniel(빡일) 2020. 5. 27. 20:28
반응형

 

 

프로그래머스 문제입니다.

문제 설명

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

 

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

 


제한사항

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

입출력 


입출력 설명

[1,2,3]이 인풋 numbers 배열이라고 할 때, 배열의 인덱스에 따라서 부호를 바꿔줄 필요가 있습니다.

 

 

[예시]                

        1                    -1

   2      -2          2      -2        

3  -3  3  -3     3  -3  3  -3

 

<--> 마지막 leaf에서 [1, 2, 3], [1, 2, -3] ... 와 같이 모든 경우의 수가 고려되어야 합니다.


문제풀이

function solution(numbers, target) {
    var answer = 0
    
    // (1)
    function dfs(nodeList, idx) {
    	// (2)
        if (idx < nodeList.length) {
          // (3)
            nodeList[idx] *= 1
            dfs(nodeList, idx+1)
            nodeList[idx] *= -1
            dfs(nodeList, idx+1)
        } else {
          // (4)
            const sum = nodeList.reduce((acc, cur) => acc + cur)
            if (sum === target) answer++ 
        }
    }
    // (5)
    dfs(numbers, 0)
    return answer
}

 

 

idea: dfs를 하기 위해서 재귀함수를 사용합니다.

1.  dfs 함수 선언

2. idx(즉, 깊이)가 nodeList의 길이보다 크지 않을 때 재귀함수를 통해 더 깊게 탐색합니다.

3. 해당 idx에 양수, 음수인 경우로 나누어 탐색합니다. 

   idx를 하나씩 증가시키면서 depth를 늘려갑니다.

4. (2)의 case가 아닌 경우입니다.

    즉, leaf 노드까지 도달했을 때, sum을 통해 target과 같을 경우, answer의 값을 증가시켜줍니다.

5. 1~4의 로직과정인 dfs 함수를 실행시킵니다.

그리고 return!

반응형