문제풀이/일일연습문제

99클럽 코테 스터디 11일차 TIL + 프로그래머스/2/43165. 타겟 넘버

Mo_bi!e 2024. 5. 31. 10:29

문제 설명

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 합니다.\

 

<코드>

def solution(numbers, target):
    
    def dfs(index, current_sum):
        # 배열의 끝에 도달한 경우
        if index == len(numbers):
            # 현재까지의 합이 타겟 넘버와 같은지 확인
            return 1 if current_sum == target else 0
        
        # 현재 숫자를 더하거나 빼는 두 가지 경우에 대해 재귀적으로 호출
        return dfs(index + 1, current_sum + numbers[index]) + dfs(index + 1, current_sum - numbers[index])
    
    return dfs(0, 0)

 

 

<포인트>

각 노드에서 두 가지 선택: 현재 숫자를 더하거나 빼는 선택이 있습니다.
리프 노드에서 조건 체크: 모든 숫자를 사용한 경우, 합계가 타겟과 같은지 확인합니다.
재귀적 탐색: 재귀적으로 각 선택지에 대해 탐색합니다.

 

- 시각화

                            0
                 +1 /           \ -1
                   1              -1
            +1 /      \ -1    +1 /    \ -1
             2           0      0       -2
       +1 /    \ -1   +1 / \ -1 +1 / \ -1 +1 / \ -1
       3         1     1   -1   1  -1  -1  -3
  +1 /  \ -1  +1 / \ -1  +1 / \ -1 +1 / \ -1 +1 / \ -1 +1 / \ -1 +1 / \ -1 +1 / \ -1 +1 / \ -1
   4     2    2   0   2   0    0  -2   2   0  0  -2 -2  -4   0  -2 -2  -4
+1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1 +1/\-1
5  3  3  1  3  1  1 -1  3  1  1 -1 -1 -3  3  1  1 -1 -1 -3 -1 -3  1 -1 -1 -3 -1 -3 -3 -5

 

<반성>

DFS, BFS 는 좀 더 공부가 필요한것 같음

 

주요 용도부터 고민해 보자!

DFS는 모든경로 탐색 / BFS는 최단경로 탐색(or 레벨 탐색 문제)

이렇게 서로 다르다

 

이 문제의 경우 모든 연산의 경우의 조합을 찾아야 하므로 DFS가 바람직함

 

첫번째 이유

모든경로 탐색을 할 수 있기 때문

두번째 이유

재귀적 호출로 모든경로 탐색이 가능하며, 재귀를 할때 각 숫자를 더하거나 빼는 선택지 고려로 가능함

세번째 이유

DFS를 이용하면 단순함