Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 괄호 검사 프로그램
- 프로그래머스 배열만들기4
- 값/참조/주소에 의한 전달
- 유형 변환
- 원형 연결 구조 연결된 큐
- 문제해결 단계
- C언어 스택 연산
- 네트워크 결합
- r-value참조자
- C언어 계산기 프로그램
- auto 키워드
- 입출력 관리자
- IPv4 주소체계
- 백준 파이썬
- const화
- c언어 괄호검사
- 문자형 배열
- getline()함수
- 논리 연산
- 알고리즘 조건
- 주기억장치
- 운영체제 기능
- 프로그래머스 푸드 파이트 대회
- const l-value참조자
- string유형
- C언어 덱
- l-value참조자
- 범위 기반 for문
- LAN의 분류
- 회전 및 자리 이동 연산
Archives
- Today
- Total
chyam
[알고리즘]- 탐색(DFS,BFS) + 문제 본문
1. DFS(깊이 우선 탐색) - 스택/재귀 함수
시작 정점에서부터 임의의 방향으로 갈수있는 곳까지 깊이 탐색하다가 더이상 갈 곳이 없으면 가장 마지막에 만났던 갈림길로 되돌아와 다른 방향을 다시 탐색합니다.
탐색은 아직 방문하지 않은 정점에 대해서만 진행해야하므로 방문한 정점에는 반드시 표시를 해둬야합니다.
먼저, 재귀로 작성한 코드입니다.
def dfs(graph, v, visited):
visited[v] = True # 방문 처리
print(v, end=' ')
for i in graph[v]: # v번 노드와 연결된 노드들
if not visited[i]: # 방문하지 않았으면
dfs(graph, i, visited) # 방문하기
graph = [ # n번 노드와 연결된 정보들
[],
[2,3,8],
[1,7],
[1,4,5],
[3,5],
[3,4],
[7],
[2,6,8],
[1,7]
]
visited = [False] * len(graph) # 방문 안함을 False로 표시
dfs(graph, 1, visited)
두번째로는 스택을 이용하여 작성한 코드입니다.
def dfs_stack(graph, start):
visited = [False] * len(graph) # 방문 여부를 저장
stack = [start] # 시작 노드를 스택에 추가
while stack: # 스택이 빌 때까지 반복
v = stack.pop() # 스택에서 가장 위의 노드를 꺼냄
if not visited[v]: # 방문하지 않았다면
print(v, end=' ') # 현재 노드 출력
visited[v] = True # 방문 처리
# 현재 노드와 연결된 노드를 스택에 추가
# (역순으로 추가해야 DFS 순서가 올바르게 유지됨.)
for i in sorted(graph[v], reverse=True):
if not visited[i]:
stack.append(i)
graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
dfs_stack(graph, 1)
2. BFS(너비 우선 탐색) - 큐
시작 정점으로부터 가까운 정점을 먼저 방문하고 멀리 떨어져 있는 정점을 나중에 방문합니다. 최단 경로를 구할때 많이 사용됩니다.
deque를 사용하지 않고 리스트로 구현을하면 dfs와 스택과 큐말고는 차이가 없습니다.
def bfs(graph, start):
visited = [False] * len(graph) # 방문 여부를 저장
queue = [start] # 큐를 리스트로 생성
visited[start] = True # 시작 노드 방문 처리
while queue: # 큐가 빌 때까지 반복
v = queue.pop(0) # 큐의 첫 번째 요소를 꺼냄
print(v, end=' ') # 현재 노드 출력
# 현재 노드와 연결된 노드들을 큐에 추가
for i in graph[v]:
if not visited[i]: # 방문하지 않은 노드라면
queue.append(i) # 큐에 추가
visited[i] = True # 방문 처리
graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
bfs(graph, 1)
deque를 사용하면 시간효율이 좋습니다.
from collections import deque
def bfs(graph, start):
visited = [False] * len(graph) # 방문 여부를 저장
queue = deque([start]) # 시작 노드를 큐에 추가
visited[start] = True # 시작 노드 방문 처리
while queue: # 큐가 빌 때까지 반복
v = queue.popleft() # 큐에서 가장 앞의 노드를 꺼냄
print(v, end=' ') # 현재 노드 출력
# 현재 노드와 연결된 노드들을 큐에 추가
for i in graph[v]:
if not visited[i]: # 방문하지 않은 노드라면
queue.append(i) # 큐에 추가
visited[i] = True # 방문 처리
graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
bfs(graph, 1)
아래는 프로그래머스에서 dfs를 이용하여 푼 문제입니다.
https://school.programmers.co.kr/learn/courses/30/lessons/87946
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
visited=[] # 방문 여부 저장
def dfs(k,dungeons,cnt):
max_cnt=cnt # 최대 던전 수
for i in range(len(dungeons)):
if i not in visited and dungeons[i][0]<=k: # 방문하지 않고 최소 피로도가 k 이하일때
visited.append(i) # i번째 방문
max_cnt=max(max_cnt,dfs(k-dungeons[i][1],dungeons,cnt+1)) # 모든 노드들 방문
visited.pop() # 방문 비워주기
return max_cnt
def solution(k, dungeons):
cnt=dfs(k,dungeons,0)
return cnt