깊이/너비 우선 탐색(DFS/BFS) - 타겟넘버 (Lv.2)

2022. 3. 6. 16:162022/Programmers

문제 설명

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 target return
[1, 1, 1, 1, 1] 3 5
[4, 1, 2, 1] 4 2
 

입출력 예 설명

 

입출력 예 #1

문제 예시와 같습니다.

 

입출력 예 #2

+4+1-2+1 = 4
+4-1+2-1 = 4
  • 총 2가지 방법이 있으므로, 2를 return 합니다.

 

<My Source Code 1>

def solution(numbers, target):
    answer = 0
    result = []; temp = []; idx = 0
    while idx < len(numbers):
        if len(result) == 0:
            temp.append(numbers[idx])
            temp.append(-1 * numbers[idx])
        else:
            for acc in result:
                temp.append(acc + numbers[idx])
                temp.append(acc - numbers[idx])

        idx += 1; result = temp; temp = []

    return result.count(target)

일단 이렇게 풀었는데 여기서 바라는 'DFS/BFS'는 아닌거 같다...

 

일단 2개의 풀이를 참고 했는데, 

 

-1- 

하나는 내가 푼 풀이법이랑 유사한데 다만 몰랐던 함수를 사용해서 기록을 하려한다.

from itertools import product
def solution(numbers, target):
    l = [(x, -x) for x in numbers]
    s = list(map(sum, product(*l)))
    return s.count(target)

itertools 패키지의 product 메소드는 2개 이상의 리스트 조합을 구할 때 사용한다.

따라서 numbers = [4, 1, 2, 1]일 때, 

ㅣ = [(4, -4), (1, -1), (2, -2), (1, -1)] 이고, 리스트 안의 set 끼리 조합을 통해 더한 값을 s로 반환한다.

따라서  s = [8, 6, 4, 2, 6, 4, 2, 0, 0, -2, -4, -6, -2, -4, -6, -8]이 된다.

 

-2-

여러 사람들이 푼 문제 중에 가장 정석인거 같아 가져와봤다.

answer = 0
def DFS(idx, numbers, target, value):
    global answer
    N = len(numbers)
    if(idx== N and target == value):
        answer += 1
        return
    if(idx == N):
        return

    DFS(idx+1,numbers,target,value+numbers[idx])
    DFS(idx+1,numbers,target,value-numbers[idx])
def solution(numbers, target):
    global answer
    DFS(0,numbers,target,0)
    return answer

재귀함수를 사용한 풀이이다...

재귀함수를 사용해 idx가 끝까지 왔을 때 target과 동일하면 +1을, 다르면 그냥 return 함으로서 카운팅 가능하고, 

각 수는 + 또는 - 연산이 가능하므로 DFS(idx+1,numbers,target,value+numbers[idx])와 DFS(idx+1,numbers,target,value-numbers[idx]) 두가지 방식으로 호출한다.