Home [Lv.2] 타겟 넘버
Post
Cancel

[Lv.2] 타겟 넘버

문제 n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.

제한조건
  • 주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
  • 각 숫자는 1 이상 50 이하인 자연수입니다.
  • 타겟 넘버는 1 이상 1000 이하인 자연수입니다.

입출력 예시
numberstargetreturn
[1, 1, 1, 1, 1]35
[4, 1, 2, 1]42

C#

이진트리 깊이 우선 탐색(DFS)을 활용해 [+][-]를 했을 때의 결과를 비교, target값 동일할 때의 개수를 확인 넘겨주는 방식으로 진행한다.

풀이 이미지

  1. 이진 트리를 생성한다. (인덱스 == 레벨)
  2. DRL(전위 순회 )하며 하위 자식과 합한 값을 stack에 넣는다.
  3. 순회를 마친 노드는 스택에서 제거한다
  4. 최하위 레벨에 있는 노드의 합이 target과 같은 경우 카운트를 1 증가한다.
  5. 모든 순회를 마치고 카운트 값을 반환한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Collections.Generic;

public class TreeNode
{
	public TreeNode(int num)
	{
		Number = num;
		LeftNode = null;
		RightNode = null;
	}

	public int Number;
	public TreeNode LeftNode;
	public TreeNode RightNode;
}

public class Solution
{
	int answer = 0;
	int targetNum = 0;

	Stack<int> traversalSum = null;

	public int solution(int[] numbers, int target)
	{
		targetNum = target;

		traversalSum = new Stack<int>();
		traversalSum.Push(0);

		TreeNode rootNode = new TreeNode(0);
		InitBinaryTree(rootNode, 0, numbers, numbers.Length - 1);

		CheckedSum(rootNode);

		return answer;
	}

	private void InitBinaryTree(TreeNode node, int index, int[] numbers, int max)
	{
		if (index == max)
		{
			if (node.LeftNode == null)
				node.LeftNode = new TreeNode(numbers[index]);

			if (node.RightNode == null)
				node.RightNode = new TreeNode(numbers[index] * -1);
			return;
		}

		if (node.LeftNode == null)
		{
			node.LeftNode = new TreeNode(numbers[index]);
			InitBinaryTree(node.LeftNode, index + 1, numbers, max);
		}

		if (node.RightNode == null)
		{
			node.RightNode = new TreeNode(numbers[index] * -1);
			InitBinaryTree(node.RightNode, index + 1, numbers, max);
		}
	}


	private void CheckedSum(TreeNode node)
	{
		if (node.LeftNode == null)
		{
			if (traversalSum.Pop() == targetNum)
                answer++;
            
			return;
		}

		else
		{
			traversalSum.Push(traversalSum.Peek() + node.LeftNode.Number);
			CheckedSum(node.LeftNode);
		}

		if (node.RightNode != null)
		{
			traversalSum.Push(traversalSum.Peek() + node.RightNode.Number);
			CheckedSum(node.RightNode);
		}

		traversalSum.Pop();
	}
}

[성공] 배열의 인덱스를 이진트리의 레벨 값으로 옮기는 과정이 힘들었지만 성공!

풀고 나서 다른 사람의 풀이를 보니 훨씬 간단하게 푸는 과정이 있었다. 재귀함수… 더 많이 공부해야겠다…!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;

public class Solution
{
	static int DFS(int[] arr, int target, int idx, int num)
	{
		if (idx == arr.Length)
		{
			if (target == num) return 1;
			else return 0;
		}
		else
			return DFS(arr, target, idx + 1, num + arr[idx]) + DFS(arr, target, idx + 1, num - arr[idx]);
	}

	public int solution(int[] numbers, int target)
	{
		return DFS(numbers, target, 0, 0);
	}
}

마지막 depth가지 내려갔다가, [+]연산, [-]연산을 하고, 한 단계 위 depth에서 다시 [+], [-] 연산을 반복함. 재귀함수 이후 재귀함수 호출 전 상태로 돌아온다는 것을 잘 이용하기!!


프로그래머스에서 문제 확인

This post is licensed under CC BY 4.0 by the author.