-
프로그래머스 - 타겟 넘버 [자바]Algorithms/- 프로그래머스 2022. 1. 30. 17:51
- 문제 링크 : 타겟 넘버
코딩테스트 연습 - 타겟 넘버
n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수
programmers.co.kr
정답
1. 재귀 : dfs함수가 int를 리턴하는 풀이
class Solution { public int solution(int[] numbers, int target) { int answer = 0; answer = dfs(numbers, 0, 0, target); return answer; } private int dfs(int[] numbers, int nodeNum, int sum, int target){ if(nodeNum == numbers.length){ if(sum == target){ return 1; }else{ return 0; } }else{ return dfs(numbers, nodeNum + 1, sum - numbers[nodeNum], target) + dfs(numbers, nodeNum + 1, sum + numbers[nodeNum], target); } } }
2. 재귀 : dfs함수가 void로 아무것도 리턴하지 않는 풀이
class Solution { private int answer = 0; public int solution(int[] numbers, int target) { dfs(numbers, 0, target, 0); return answer; } private void dfs(int[] numbers,int depth, int target, int sum){ if(numbers.length == depth){ if(sum == target){ answer++; } return; } dfs(numbers, depth + 1, target, sum - numbers[depth]); dfs(numbers, depth + 1, target, sum + numbers[depth]); } }
3. Stack 풀이
import java.util.*; class Solution { private class Val{ int depth, sum; Val(int depth, int sum){ this.depth = depth; this.sum = sum; } } public int solution(int[] numbers, int target) { int answer = 0; Stack<Val> stk = new Stack<>(); stk.push(new Val(0, 0)); while(!stk.isEmpty()){ Val val = stk.pop(); if(val.depth < numbers.length){ stk.push(new Val(val.depth + 1, val.sum + numbers[val.depth])); stk.push(new Val(val.depth + 1, val.sum - numbers[val.depth])); }else{ if(val.sum == target){ answer++; } } } return answer; } }
분석
깊이 우선 탐색(Depth-First Search, DFS)이나 너비 우선 탐색(Breadth-First Search, BFS)으로 풀 수 있는 문제이다.
BFS 보다 DFS가 간편하여 DFS로 풀이 하였다.
return 에서 +를 기준으로 sum에서 - 와 +를 해주어 -1, +1을 할 수 있도록 하였다.
if문에서 sum과 target이 같은 경우만 1을 리턴하여 target 값이 몇 개가 있는지 마지막 결과로 받을 수 있다.
함수 형식 : dfs(숫자배열, 차수, 총합, 목표값) return dfs() + dfs()
참조한 코드
• C
#include <stdio.h> #define N 7 int g[N][N]= { {0,1,0,0,0,1,1}, {1,0,1,1,0,0,0}, {0,1,0,0,1,0,0}, {0,1,0,0,0,0,0}, {0,0,1,0,0,0,0}, {1,0,0,0,0,0,1}, {1,0,0,0,0,1,0} }; int visited[N]; void dfs(int here) { //here이 이미 방문된 정점 return if (visited[here]) return; printf("정점 %d를 방문\n", here); visited[here] = 1; //here 정점은 방문 for (int next = 0; next < N; next++) //그래프가 이어져있으면서, 아직 다음 정점이 방문되지 않았으면 dfs 수행 if (g[here][next] == 1 && !visited[next]) dfs(next); } int main() { dfs(0); }
• Java
/* 0 : 연결 안됨 1 : 연결됨 아래 단순 7개의 정점 있는 그래프를 표현 한 것 노드 1 - 노드 2 - 노드 6 - 노드 7 노드 2 - 노드 1 - 노드 3 - 노드 4 노드 3 - 노드 2 - 노드 5 노드 4 - 노드 2 노드 5 - 노드 3 노드 6 - 노드 1 - 노드 7 노드 7 - 노드 1 - 노드 6 * 그림 * 노드 1 --- 노드 2 --- 노드 3 --- 노드 5 ㅣ ㅣ ㅣ ㅣ------ 노드 4 ㅣ ㅣ------ 노드 6 ㅣ ㅣ ㅣ------ 노드 7 */ int[][] graph = { {0,1,0,0,0,1,1}, {1,0,1,1,0,0,0}, {0,1,0,0,1,0,0}, {0,1,0,0,0,0,0}, {0,0,1,0,0,0,0}, {1,0,0,0,0,0,1}, {1,0,0,0,0,1,0} }; int[] visited = new int[graph.length]; private void dfs(int nodeNum){ /*방문된 정점이라면 뒤로 가기*/ if(visited[nodeNum]){ return; } /*현재 정점은 방문*/ visited[nodeNum] = 1; for(int next = 0; next < graph.length; next++){ /*그래프가 이어져 있으며 아직 다음 정점을 방문하지 않았으면*/ if(graph[nodeNum][next] == 1 && !visited[nodeNum]){ /*다음 정점에서 dfs*/ dfs(next); } } } dfs(0);
반응형