2022 스터디/알고리즘 스터디[2022]

[DFS/BFS] 타겟 넘버

EYR 2022. 5. 2. 13:35

 

 

  DFS/BFS 두 가지 방식 모두 그래프를 탐색하는 방법이다.

그저 그래프를 탐색하는 것 만으로도 해결될 수 있는 문제가 많기 때문에 그래프 탐색은 중요하다.


그래프

그래프는 정점간선들 사이의 유한 집합으로 이루어진 자료구조의 일종.

정점은 노드라고도 불리며, 간선은 링크라고도 불린다.

(정점:vertex, 노드:node, 간선:edge, 링크:link)

 

그래프의 표현방식

  • 인접 행렬: 2차원 배열

그래프의 정점 수: n

n*n의 2차원 배열인 인접행렬로 표현할 수 있다.

 

ex) M[i][l] = 1 (i과 l이 연결되어 있을 때)

     M[i][l] = 0 (연결되지 않을 때)

 

정점이 3개라면 다음처럼 표현될 수 있다.

[[1, 1, 0], [1, 1, 0], [0, 0, 1]]

 

1 1 0

1 1 0

0 0 1

 

n번째 배열의 n번째 요소는 자기자신이기 때문에 항상 1

참고: https://programmers.co.kr/learn/courses/30/lessons/43162

 

코딩테스트 연습 - 네트워크

네트워크란 컴퓨터 상호 간에 정보를 교환할 수 있도록 연결된 형태를 의미합니다. 예를 들어, 컴퓨터 A와 컴퓨터 B가 직접적으로 연결되어있고, 컴퓨터 B와 컴퓨터 C가 직접적으로 연결되어 있

programmers.co.kr

여기서 주어지는 형태가 인접행렬

 

  • 인접 리스트: 연결 리스트

각각의 정점에 인접한 정점들을 연결 리스트로 표시한 것.

각 노드들은 인접 정점을 저장하게 된다.

 

ex)

https://kingpodo.tistory.com/46

 

6-2. 그래프의 표현(인접 행렬, 인접 리스트, 인접 다중 리스트)

1. 그래프의 표현 그래프를 표현하는 방법은 여러가지가 있지만 그 중 대표적인 방법이 인접행렬(adjacency matrix), 인접 리스트(adjacency list), 인접 다중 리스트(adjacency multi list)이다. 이때 어떤 표현

kingpodo.tistory.com

 

인접 행렬이 항상 n^2개의 저장공간을 요구하는 것과는 다르게 인접 리스트는

(정점: n 간선:e일때) n개의 헤더 노드와 2e개의 노드만 필요하기 때문에

간선의 개수가 적은 희소 그래프에 적합하다.

*무방향이기 때문에 2e개, 단방향이면 e개

 

 

 

 

 

 

 

 


1. DFS - 깊이 우선 탐색

DFS[Depth First Search] - 깊이 우선 탐색

 

  트리 탐색과 비슷하다.

  시작 정점에서 한 방향으로 계속 가다 더 이상 갈 수 없게 되면 가장 가까운 갈림길로 돌아와서 가른 방향으로 다시 탐색을 진행하는 방법. (사진자료: https://devuna.tistory.com/32)

미로찾기 등

 

 시작 정점에서 시작해서 한 깊이를 완벽하게 탐색하는 방식.

 

 

특징

  • BFS보다 간단하게*재귀 구현이 가능하다.
  • 검색 속도는 BFS보다 느리다. (한 깊이-경로-로 깊게 파고 들어갈 수 있기 때문에)
  • 현 경로상의 노드만을 기억하기 때문에 저장공간의 수요가 비교적 적음.
  • 얻어진 답으로 가는 경로가 최단 경로가 아닐 가능성이 있다. (적은 수부터 깊이 탐색을 한다면)

 

구현

스택 또는 재귀함수

 

(자료 : https://choiiis.github.io/algorithm/practice-dfs/)

스택 > 깊이 순으로 집어넣다가 인접 노드가 없으면 인접 노드가 있는 곳까지 스택에서 제거

방문한 노드는 꼭 방문처리 해주어야 무한 루프에 빠지지 않는다.

 

재귀> 더 이상 방문할 노드가 없으면 함수를 종료한다. (값을 return받아 경로의 정보나 특성을 얻기에 유용)

 

 

시간 복잡도

인접 리스트: O(n+e)

인접 행렬: O(n^2)

*희소 그래프인 경우 우선 탐색은 인접 리스트의 사용이 인접 행렬보다 빠르다.

 

 

 

 

 


2. BFS - 너비 우선 탐색

BFS[Breath First Search] - 너비 우선 탐색

  시작 정점으로부터 가까운 정점을 먼저 방문하고 멀리 떨어져 있는 정점을 나중에 방문.

시작으로부터 인접한 정점를 먼저 탐색하고 멀리 떨어져 있는 곳을 나중에 탐색.

최단 경로를 찾을 때 이 방법을 주로 사용한다.

 

 

구현

 

깊이 별로 큐에 집어넣은 후, 인접 노드를 집어넣고, 그 이전 깊이에 있었던 노드는

제거하는 식으로 탐색을 진행한다.

 

 

 

시간 복잡도

인접 리스트: O(n+e)

인접행렬: O(n^2)

모든 노드를 탐색하는 과정이기 때문에

표현하는 방식에 영향을 받을 수 밖에 없다.

같은 이유로 두 방식에서의 시간 복잡도는 차이가 없다.

 

 

특징

  • 직관적이지 않은 면이 있다
  • 지나온 경로를 체크하여 무한 루프에 빠지지 않게 하는게 중요하다.
  • 큐를 사용한다.(선입선출 원칙)

 

 

 

둘을 사용하기 좋은 문제

1) 그래프의 모든 정점 방문 (DFS, BFS)

2) 경로의 특징 저장 (DFS), BFS는 경로의 특징을 가지지 못함

3) 최단거리 구하기 (BFS)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

타겟 넘버

https://programmers.co.kr/learn/courses/30/lessons/43165

 

코딩테스트 연습 - 타겟 넘버

n개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수

programmers.co.kr

DFS방식

def solution(numbers, target):
    def DFS(total, depth):
        if (depth == len(numbers)): #만약 끝에 다다르고
            if (total == target): #합이 target과 같다면
                return 1
            else: return 0;
        else:
            return (DFS(total+numbers[depth], depth+1) + 
                    DFS(total-numbers[depth], depth+1))
    
    answer = DFS(0,0)
    return answer

 

 

BFS방식

 

 

 

 

-

참고자료

https://devuna.tistory.com/32

https://velog.io/@lucky-korma/DFS-BFS%EC%9D%98-%EC%84%A4%EB%AA%85-%EC%B0%A8%EC%9D%B4%EC%A0%90

https://yunyoung1819.tistory.com/86

https://better-tomorrow.tistory.com/entry/DFS-BFS-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

https://gmlwjd9405.github.io/2018/08/15/algorithm-bfs.html

 

 

 

'2022 스터디 > 알고리즘 스터디[2022]' 카테고리의 다른 글

정렬  (0) 2023.03.18
[Greedy] 체육복  (0) 2022.05.16
[해시] 완주하지 못한 선수  (0) 2022.04.11