출처 : 프로그래머스
문제 설명
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 |
입출력 예 설명
문제에 나온 예와 같습니다.
풀이과정
1. 무조건 방문 체크를 해야할 것 같다.
2. 각 요소를 방문체크하면서 모든 경우의 수를 따져본다..?
작성 코드
class Solution {
public static int answer = 0;
public int solution(int[] numbers, int target) {
dfs(numbers,target,0);
return answer;
}
public static int dfs(int[] numbers,int target,int index) {
if(numbers.length == index) {
int sum = 0;
for(int num : numbers) {
sum += num;
}
if(sum == target)
answer ++;
} // numbers 갯수 만큼만 dfs탐색
else {
numbers[index] *= 1;
dfs(numbers,target,index+1);
numbers[index] *= -1;
dfs(numbers,target,index+1);
} // 계속 탐색
return answer;
}
}
memo
처음 생각했던 것처럼 방문 체크는 하지 않아도 된다.
DFS 탐색의 재귀 구현을 이용하면 된다는 것을 알았다.
그 외에도 중요한 것이 있다.
- 타겟 넘버는 1 이상 1000 이하인 자연수입니다
이것이 중요한 이유는
위의 코드에서 dfs 탐색 시 음수를 먼저 따지고 , 양수를 그 후에 따지는 방식으로 바꿔서 실행시켜보면 오답이 나오기 때문이다.
트리를 직접 그려보고 문제에서 타겟넘버가 자연수라는 제한조건을 생각해보면 답이 나올 것 같다.
1. index, 즉, 배열의 길이만큼 탐색을 한다는 점
2. 문제에서 자연수를 구한다는 조건
그런데 음수부터 따지면 음수가 먼저 붙는 케이스만 따져보다가 깊이에 다다라서 재귀호출이 끝나게된다.
그래서 return 값이 5 가 아닌 2가 나오게 되어 틀리다고 판정받았다.
실력이 모자라 횡설수설하지만 일단 결론은 탐색 시 양수를 왼쪽 노드, 음수를 오른쪽 노드로 생각하는 것을 디폴트로 해두어야겠다.
아래 그림은 오답 이유를 찾다가 찾게 된 참고 그림이다.

'머리맞대는이야기 > 프로그래머스 (JAVA)' 카테고리의 다른 글
| [Summer/Winter Coding] 스킬트리 (0) | 2020.10.16 |
|---|---|
| [깊이/너비 우선 탐색(DFS/BFS)] 네트워크 (0) | 2020.09.27 |
| [연습문제] 124 나라의 숫자 (0) | 2020.09.14 |
| [해시] 베스트앨범 (0) | 2020.09.06 |
| [연습문제] 시저 암호 (0) | 2020.09.06 |