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);
반응형