깊이 우선 탐색 (DFS)
루트 노드(혹은 다른 임의의 노드)에서 시작해서 다음 분기(branch)로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법
// 문제가 dfs라 생각되면 해당 graph를 설계를 하고난후 밑에 코드만 접목시키면 된다.
graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
# 방문노드
visited = [False] * len(graph)
def dfs(graph, v, visited):
visited[v] = True
print(v, end=' ')
for i in graph[v]:
if not visited[i]:
visited[i] = True
dfs(graph, i, visited)
# 0번 노드가 없으니 1번 노드부터 탐색
dfs(graph, 1, visited)
넓이 우선 탐색 (BFS)
루트 노드(혹은 다른 임의의 노드)에서 시작해서 인접한 노드를 먼저 탐색하는 방법
def bfs(graph, v, visited):
queue = deque([start])
visited[v] = True
while queue:
v = queue.popleft()
print(v, end=' ')
for i in graph[v]:
if not visited[i]:
visited[i] = True
graph = [
[],
[2, 3, 8],
[1, 7],
[1, 4, 5],
[3, 5],
[3, 4],
[7],
[2, 6, 8],
[1, 7]
]
# 방문노드
visited = [False] * len(graph)
# 0번 노드가 없으니 1번 노드부터 탐색
bfs(graph, 1, visited)
DFS와 BFS 예제를 풀어보자
n개의 음이 아닌 정수가 있습니다. 이 수를 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.
사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.
bfs 풀이
import collections
def solution(numbers, target):
answer = 0
stack = collections.deque([(0, 0)])
while stack:
current_sum, num_idx = stack.popleft()
if num_idx == len(numbers):
if current_sum == target:
answer += 1
else:
number = numbers[num_idx]
stack.append((current_sum+number, num_idx + 1))
stack.append((current_sum-number, num_idx + 1))
return answer
dfs 풀이
from collections import deque
def solution(numbers, target):
answer = 0
n = len(numbers)
def dfs(index, value):
nonlocal answer
if index == n:
if value == target:
answer += 1
return
else:
dfs(index + 1, value + numbers[index])
dfs(index + 1, value - numbers[index])
dfs(0,0)
return answer
풀이 후 느낀점
네트워크란 컴퓨터 상호 간에 정보를 교환할 수 있도록 연결된 형태를 의미합니다. 예를 들어, 컴퓨터 A와 컴퓨터 B가 직접적으로 연결되어있고, 컴퓨터 B와 컴퓨터 C가 직접적으로 연결되어 있을 때 컴퓨터 A와 컴퓨터 C도 간접적으로 연결되어 정보를 교환할 수 있습니다. 따라서 컴퓨터 A, B, C는 모두 같은 네트워크 상에 있다고 할 수 있습니다.
컴퓨터의 개수 n, 연결에 대한 정보가 담긴 2차원 배열 computers가 매개변수로 주어질 때, 네트워크의 개수를 return 하도록 solution 함수를 작성하시오.
dfs 풀이
def solution(n, computers):
answer = 0
arr = []
for index, data in enumerate(computers):
a = []
for i,d in enumerate(data):
if i != index and d == 1:
a.append(i)
arr.append(a)
def dfs(s):
visited[s] = 1
for i in arr[s]:
if visited[i] == 0:
dfs(i)
visited = [0] * len(arr)
for i in range(n):
if visited[i] == 0:
answer += 1
dfs(i)
return answer
풀이 후 느낀점
두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.
예를 들어 begin이 "hit", target가 "cog", words가 ["hot","dot","dog","lot","log","cog"]라면
"hit" -> "hot" -> "dot" -> "dog" -> "cog"와 같이 4단계를 거쳐 변환할 수 있습니다.
두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.
초기 풀이
def solution(begin, target, words):
answer = 0
// 바꿀수있는 단어를 반환해주는 함수
def search(a):
arr = []
for j in words:
n = 0
for i in a:
if i in j:
n += 1
if n == 2:
arr.append(j)
return arr
aa = []
if target in words:
ar = [begin]
while True:
for i in ar:
aa = search(i)
if target in aa:
answer += 1
break
answer += 1
ar = aa
return answer
bfs 풀이
from collections import deque
def solution(begin, target, words):
answer = 0
isVisited = [False]*len(words)
queue = deque()
if not target in words :
return 0
for i in range(len(words)) :
if(searchSimilar(begin,words[i])) :
queue.append([1,words[i]])
isVisited[i] = True
if words[i] == target :
answer = 1
return answer
while queue :
v = queue.popleft()
for i in range(len(words)) :
if(searchSimilar(v[1],words[i]) and isVisited[i] == False) :
queue.append([v[0]+1,words[i]])
isVisited[i] = True
if words[i] == target :
answer = v[0] + 1
return answer
return 0
def searchSimilar(begin,word):
difcount = 0
for i in range(len(begin)) :
if begin[i] != word[i] :
difcount +=1
if difcount == 1 :
return True
return False
풀이 후 느낀점