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 [1, 1, 1, 1, 1]
target 3
return 5
class Solution {
static int answer = 0 ;
public int solution(int[] numbers, int target) {
dfs(numbers,target,0);
return answer;
}
public static void dfs(int[] numbers, int target, int node){
if(node==numbers.length){
int sum = 0;
for(int num : numbers){
sum+=num;
}
if(sum==target){
answer++;
}
}else{
numbers[node]*=1;
dfs(numbers,target,node+1);
numbers[node]*=-1;
dfs(numbers,target,node+1);
}
}
}
아주 간략하게나마 설명을 해보자면
코드에서 dfs 함수에 들어가서 node가 numbers 배열의 길이와 같지 않을 경우, numbers[node]를 1로 바꾸거나 -1로 바꾸게 된다.
위의 그림에서 빨간 선은 1로 바꾼 경우를 계~~속 따라 간 것이다!
1로 4번 바꾸다가
numbers[node]*=-1;
dfs(numbers,target,node+1);
위 코드를 만나게 되면 마지막을 -1로 바꾸게 되고 이는 위 그림에서 파란색 파란색 선을 따라가게 된다.
1로 3번 바꾸다가
numbers[node]*=-1;
dfs(numbers,target,node+1);
위 코드를 만나면 보라색 선을 따라가게 될 것이다.
DFS 글에서 봤듯 순회를 하게 되는데 이를 재귀 방식으로 구현하였다.
모든 경우를 다 따져가며 우리가 찾고자 하는 target과 값이 일치할 경우, count를 올려주는 형식이다.
class Solution {
static int answer = 0;
public int solution(int[] numbers, int target) {
dfs(numbers, 0, 0, target);
return answer;
}
public static void dfs(int[] numbers, int index, int result, int target){
if(index==numbers.length){
if(result==target){
answer++;
}
}else{
index++;
dfs(numbers, index, result+numbers[index-1], target);//더하는 경우,
dfs(numbers, index, result-numbers[index-1], target);//빼는 경우,
}
}
}
dfs,bfs는 주기적으로 하지 않으면 자꾸 잊게 된다.
그래서 일단 2단계 문제 부터 집었다. 이전보다 빨라진듯?👀