[프로그래머스] 타겟 넘버 (python) - BFS/DFS

2022. 3. 14. 22:32·Algorithms 💻/Programmers
반응형

# 문제 

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 함수를 작성해주세요.

 

# 아이디어 

노드 엣지로 구성된 그래프를 그릴 수 있는 상하좌우, map 문제 뿐 아니라 이런 것도 bfs/dfs 문제임을 깨닫게 해준 문제. 이진 트리 형식으로 뻗어나갈 수 있는 문제는 dfs/bfs로 접근할 수 있음을 항상 염두해 두어야겠다. 

이 문제의 접근방식을 손그림으로 표현하면 다음과 같다. 가장 main idea는 +, - 부호에 따른 각 숫자에서 2가지 경우의 수가 생산된다는 것이다. 따라서 numbers의 각 숫자에 따라 2가지 경우로 자손을 뻗을 수 있게되고, 모든 경우의 수를 탐색하는 bfs/dfs 문제가 된다. (여기서 모든 경우의수가 2^n이라는 것을 문제로 추론할 수 있을 것이다. 하지만 numbers의 개수가 20개 이하이므로, 모든 경우를 탐색하는 것도 괜찮은 것 같다. ).

이러한 트리를 너비우선으로 넓게 탐색하면 bfs, 깊게 경우 하나하나 탐색하면 dfs로 해결할 수 있는 것이다. 

 

# Code

우선 BFS로 풀이한 코드는 다음과 같다. 

def solution(numbers, target):
  leaves = [0]          # 모든 계산 결과를 담자      
  count = 0 

  for num in numbers : 
    temp = []
	
    # 자손 노드 
    for leaf in leaves : 
      temp.append(leaf + num)    # 더하는 경우 
      temp.append(leaf - num)    # 빼는 경우 

    leaves = temp 

  # 모든 경우의 수 계산 후 target과 같은지 확인 
  for leaf in leaves : 
    if leaf == target : 
      count += 1

  return count

 

 

다음은 DFS로 풀이한 코드이다. 참고로 DFS는 다음과 같이 작동하는 알고리즘으로, 주로 재귀함수로 구현한다. 코드 내 재귀함수가 무한루프로 돌지 않도록 종료 조건이 있는지 잘 확인하는게 중요하다 ! 

def dfs(numbers, target, idx, values):     # idx : 깊이 / values : 더하고 뺄 특정 leaf 값 
	
    global cnt
    cnt = 0 
	
    # 깊이가 끝까지 닿았으면 
    if idx == len(numbers) & values == target : 
    	cnt += 1
        return 
  
    # 끝까지 탐색했는데 sum이 target과 다르다면 그냥 넘어간다
    elif idx == len(numbers) : 
    	return 
    
    # 재귀함수로 구현 
    dfs(numbers, target, idx+1, values + numbers[idx])   # 새로운 value 값 세팅   
    dfs(numbers, target, idx+1, values - numbers[idx])
 
 def solution(numbers, target) : 
 	
    global cnt
    dfs(numbers, target, 0, 0)
    
    return cnt

위 dfs 코드에 대해 설명을 추가하자면 (사실 내가 잘 이해가 안간다. ㅎㅎ)

  • cnt를 global 변수로 지정해줘야한다. solution 함수에서 접근 가능해야하기 때문이다. 
  • idx는 DFS의 depth를 나타내는 변수이다. 하지만 이 문제에서 depth는 리스트 원소들의 차례를 의미하므로 리스트의 인덱스로서 작용할 수도 있을 것이다. 따라서 idx 값이 numbers 리스트의 len 값과 같다면 dfs를 중단 해야한다. (재귀함수의 중단조건이 된다)
  • DFS 내 values 값을 +, - 로 업데이트 하며 재귀함수가 작용한다. 

 

많이 배웠던 문제인 것 같다 :) 

반응형
저작자표시 (새창열림)

'Algorithms 💻 > Programmers' 카테고리의 다른 글

[프로그래머스] 네트워크 (python) - BFS/DFS  (2) 2022.03.15
'Algorithms 💻/Programmers' 카테고리의 다른 글
  • [프로그래머스] 네트워크 (python) - BFS/DFS
당니이
당니이
씩씩하게 공부하기 📚💻
  • 당니이
    다은이의 컴퓨터 공부
    당니이
  • 전체
    오늘
    어제
    • 분류 전체보기 (136)
      • Achieved 👩🏻 (14)
        • 생각들 (2)
        • TIL (6)
        • Trial and Error (1)
        • Inspiration ✨ (0)
        • 미국 박사 준비 🎓 (1)
      • Computer Vision💖 (39)
        • Basic (9)
        • Video (5)
        • Continual Learning (7)
        • Generative model (2)
        • Domain (DA & DG) (5)
        • Multimodal (8)
        • Multitask Learning (1)
        • Segmentation (1)
        • Colorization (1)
      • RL 🤖 (1)
      • Autonomous Driving 🚙 (11)
        • Geometry (4)
        • LiDAR 3D Detection (1)
        • Trajectory prediction (2)
        • Lane Detection (1)
        • HDmap (3)
      • Linux (15)
      • PyTorch👩🏻‍💻 (10)
      • Linear Algebra (2)
      • Python (5)
      • NLP (10)
        • Article 📑 (1)
      • Algorithms 💻 (22)
        • Basic (8)
        • BAEKJOON (8)
        • Programmers (2)
      • ML (1)
        • 통계적 머신러닝(20-2) (1)
      • SQL (3)
      • 기초금융 💵 (1)
  • 블로그 메뉴

    • 홈
    • About me
  • 링크

    • 나의 소박한 github
    • Naver 블로그
  • 공지사항

  • 인기 글

  • 태그

    Python
    백준
    LLM
    continual learning
    Linux
    domain generalization
    알고리즘
    dfs
    pytorch
    Incremental Learning
    domain adaptation
    NLP
    CL
    til
    자료구조
    코딩테스트
    conda
    리눅스
    백트래킹
    CV
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
당니이
[프로그래머스] 타겟 넘버 (python) - BFS/DFS
상단으로

티스토리툴바