본문 바로가기

머리맞대는이야기/프로그래머스 (JAVA)

[깊이/너비 우선 탐색(DFS/BFS)] 타겟 넘버

반응형

출처 : 프로그래머스

 

문제 설명

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가 나오게 되어 틀리다고 판정받았다.

 

실력이 모자라 횡설수설하지만 일단 결론은 탐색 시 양수를 왼쪽 노드, 음수를 오른쪽 노드로 생각하는 것을 디폴트로 해두어야겠다.

 

아래 그림은 오답 이유를 찾다가 찾게 된 참고 그림이다.

 

출처 : lkhlkh23.tistory.com/74

 

 

 

 

반응형