๊ทธ๋ํ ๊ฐ๋
- ๊ทธ๋ํ๋ ๋ ธ๋์ ๊ฐ์ ์ ์ด์ฉํ ๋น์ ํ ๋ฐ์ดํฐ ๊ตฌ์กฐ
- ๊ทธ๋ํ๋ ๋ฐ์ดํฐ ๊ฐ์ ๊ด๊ณ๋ฅผ ํํํ๋ ๋ฐ ์ฌ์ฉ.
- ๋ฐ์ดํฐ๋ฅผ ๋ ธ๋, ๋ ธ๋๊ฐ์ ๊ด๊ณ๋ ํ๋ฆ์ ๊ฐ์ ์ผ๋ก ํํ
- ๋ฐฉํฅ์ฑ :๋ฐฉํฅ์ด ์์ ์๋ ์๊ณ ์์ ์๋ ์๋ค.
- ๊ฐ์ค์น : ๋ ธ๋๊ฐ์ ๊ด๊ณ์์ ๊ฐ์ค์น๊ฐ ์์ ์๋ ์๊ณ , ์์ ์๋ ์๋ค.
- ์ฌ์ดํด : ์ํ ๊ทธ๋ํ(Cycle graph)์ ๋น์ํ ๊ทธ๋ํ(acyclic graph)๋ก ๊ตฌ๋ถ ๋ ์ ์๋ค.
๊ทธ๋ํ ๊ตฌํ ๋ฐฉ์
- ์ธ์ ํ๋ ฌ๊ณผ ์ธ์ ๋ฆฌ์คํธ ๋ฐฉ์์ ์ด์ฉํ์ฌ ๊ทธ๋ํ ํํ
์ธ์ ํ๋ ฌ
๋จ์ : ์ธ์ ํ๋ ฌ์์๋ ์ด๋ค ๋ ธ๋์ ์ธ์ ํ ๋ ธ๋๋ค์ ์ฐพ๊ธฐ ์ํด ์ธ์ ๋ฆฌ์คํธ์ ๋นํด ํจ์จ์ฑ์ด ๋จ์ด์ง๋ค. ๋ชจ๋ ๋ ธ๋๋ฅผ ์ํํด์ผ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฅ์ : ๊ฐ์ ์ ์ ๋ณด๋ฅผ ํ์ธํ ๋ O(1)์๊ฐ๋ณต์ก๋๋ก ๋งค์ฐ ํจ์จ์ ์ด๋ค. ex) 2 - 99 ๋ ธ๋์ฌ์ด์ ๊ฐ์ค์น๋ฅผ ํ์ธํ๊ธฐ ์ํด
array[2][99]
์ ๊ทผ. ์ธ์ ๋ฆฌ์คํธ ๊ฒฝ์ฐadj[2]
๋ฅผ ํตํด ์ฐ๊ฒฐ๋ ๋ชจ๋ ๋ ธ๋๋ค์ ๋ค์ ์ํํ์ฌ99
๋ฅผ ์ฐพ์์ผ ํ๋ค.
์ธ์ ๋ฆฌ์คํธ(adjacency list)
- ๊ฐ์ ์ ๋ณด ํ์ธ์ ํน์ ๋ ธ๋์์ ์์ํ์ฌ ์ฐ๊ฒฐ ๋ ธ๋ ๊ฐ์๊ฐ ๋ง์ ์๋ก, ์ฐ๊ฒฐํ ๋ ธ๋๋ค์ ๊ธธ์ด ๋งํผ ํ์ํด์ผ ํ๋ฏ๋ก O(N)์ ํ์ ์๊ฐ์ ๊ฐ์ง๋ค.
๋ฉ๋ชจ๋ฆฌ์ฌ์ฉ | ์๊ฐ๋ณต์ก๋ | ๊ธฐํ | |
---|---|---|---|
์ธ์ ํ๋ ฌ | O(N^2) | O(1) | ๊ตฌํ์ด ์๋์ ์ผ๋ก ์ฌ์ |
์ธ์ ๋ฆฌ์คํธ | O(N^2) | O(N) |
- ์ฑ ์์ ๋ ธ๋ ๊ฐ์๊ฐ 1000๊ฐ ๋ฏธ๋ง์ผ ๊ฒฝ์ฐ ์๊ฐํจ์จ ์ฅ์ ์ ํ์ฉํ ์ธ์ ํ๋ ฌ ์ฌ์ฉ๋ ์ ์๋์ด ์๋ค.
๊ทธ๋ํ ํ์
DFS(๊น์ด์ฐ์ ํ์)
์คํ์ ๊ธฐ๋ฐ์ผ๋ก ๊น์ด ์ฐ์ ํ์์ ๊ตฌํํ๋ค.
์ด ํ์์ ์ ์ฒด์ ์์ด๋์ด๋ ํ๋์ ๊น์ด (๋ ธ๋)๋ฅผ ๋ค์ด๊ฐ๋ฉด ํด๊ฒฐ์ฑ ์ด ์๋ค๊ณ ์์ํ๋ ๊ฒ์ด๋ค.
๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธํ์ ๋ ๋ฐฉ๋ฌธ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ , ๋ฐฉ๋ฌธํ ๋ ธ๋์ ์ธ์ ๋ ธ๋๋ค์ ์ํํ๋ฉฐ ๋ฐฉ๋ฌธ ํ์ง ์์์ ๊ฒฝ์ฐ ์คํ์ ๋ฃ์ด ๋ฏธ๋์ ํ์ํ ๋ ธ๋๋ฅผ ์ถ์ ํ๋ค.
a
์ ์ด์ํ ๋ ธ๋b
๋ฅผ ๋ฐฉ๋ฌธํ๋ค๋ฉด,a
์ ์ธ์ ํ ๋ค๋ฅธ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธ ํ๊ธฐ ์ ์b
์ ์ธ์ ํ ์ด์ ๋ ธ๋ ๋ค์ ์ ๋ถ ๋ฐฉ๋ฌธํด์ผ ํ๋ค.b
์ ๋ถ๊ธฐ๋ฅผ ์ ๋ถ ํ์ํ ๋ค์์ผa
์ ๋ค๋ฅธ ์ด์ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธ ํ ์ ์๋ค.์ด์ ๋ ธ๋๋ฅผ ๊ณ์ํด์ ๋ฐฉ๋ฌธํ ๋ ๋ฌดํ ๋ฃจํ ๋ฐฉ์ง ํ๊ธฐ ์ํด ํ์ฌ ๋ฐฉ๋ฌธํ ๋ ธ๋ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค.
๋ ธ๋์ ๊ฐ์- N, ๊ฐ์ ์ ๊ฐ์-E ์ผ ๊ฒฝ์ฐ,
์ธ์ ๋ฆฌ์คํธ๋ฅผ ์์ฑํ ๋๋ ๊ฐ์ ๊ฐ์๋งํผ ์ฐ์ฐํ๋ฏ๋ก ์๊ฐ ๋ณต์ก๋๋ O(E)
ํ์ ์ ๋ชจ๋ ๋ ธ๋๋ฅผ 1ํ ๋ฐฉ๋ฌธ(์ค๋ณต ์ฒ๋ฆฌ๋ก ์ธํด 1ํ ๋ฐฉ๋ฌธ ๊ฐ๋ฅ) ํ๋ฏ๋ก N๋ฒ ์ํํ๋ค. O(N)
๊ฐ ์ฐ์ฐ์ด ๋ฐ๋ก ์ด๋ฃจ์ด์ง๋ฏ๋ก O(E+V)
function solution(graph, start) {
const result = []
const adjList = {}
//์ธ์ ๋ฆฌ์คํธ ์ด๊ธฐํ
graph.forEach(([from, to]) =>
adjList[from] ? adjList[from].push(to) : (adjList[from] = [to]),
)
dfs(start, new Set()) //set ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ์ฌ ์ค๋ณต ๋ฐฉ๋ฌธ์ฒ๋ฆฌ
return result
function dfs(v, visited) {
visited.add(v) //๋ฐฉ๋ฌธ ์ฒ๋ฆฌ
result
.push(v)(
//์ธ์ ๋
ธ๋ ํ์
adjList[v] || [],
)
.forEach((w) => (!visited.has(w) ? dfs(w, visited) : null))
}
}
BFS(๋๋น ์ฐ์ ํ์)
A
๋ ธ๋์์ ์์ ํ๋ค๊ณ ํ์ ๋, BFS๋A
์ ์ด์ ๋ ธ๋(=์ธ์ ๋ ธ๋)๋ฅผ ๋ชจ๋ ๋ฐฉ๋ฌธ ํ ๋ค์ ์ด์์ ์ด์๋ค์ ๋ฐฉ๋ฌธํ๋ค.- ์ด๋ฐ ๊ตฌํ์ ์ํด์ ์๋ฃ๊ตฌ์กฐ ํ๋ฅผ ์ด์ฉํ์ฌ ํ์์ ํ๋ค.
- ์๋ฃ๊ตฌ์กฐ ํ๋ฅผ ์ด์ฉํ์ ๋ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๋ณด์ฅ ํ ์ ์๋ค.
- ์๋์ ๊ตฌํ์ ์ํด ๋ฐฉ๋ฌธ ๊ฒฝ๋ก๋ A-B-C-D-E ๋ก ๋ฃจํธ๋ก ๋ถํฐ ์ฐจ์ ๋จ๊ณ์ ์๋ ๋ชจ๋ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธ ํ ๊ฒ์ ํ์ธํ ์ ์๋ค.-> ์ต๋จ ๊ฒฝ๋ก ๋ณด์ฅ
A
| \
B C
| \
D E
queue = [A]
ํ์ ๊ฐ์ฅ ์ ๋๊ธฐ์ด ๊บผ๋ด๊ธฐ
A ๋ฐฉ๋ฌธ , queue = []
๋ฐฉ๋ฌธํ์ง ์์ ์ธ์ ๋
ธ๋ B,C ์ถ๊ฐ queue= [B,C]
ํ์ ๊ฐ์ฅ ์ ๋๊ธฐ์ด ๊บผ๋ด๊ธฐ
B ๋ฐฉ๋ฌธ, queue =[C]
๋ฐฉ๋ฌธํ์ง ์์ B์ ์ธ์ ๋
ธ๋ D์ถ๊ฐ queue = [C,D]
ํ์ ๊ฐ์ฅ ์ ๋๊ธฐ์ด ๊บผ๋ด๊ธฐ
C ๋ฐฉ๋ฌธ, queue= [D]
๋ฐฉ๋ฌธํ์ง ์์ C์ ์ธ์ ๋
ธ๋ E ์ถ๊ฐ queue= [D,E]
ํ์ ๊ฐ์ฅ ์ ๋๊ธฐ์ด ๊บผ๋ด๊ธฐ
D ๋ฐฉ๋ฌธ, queue = [E]
D์ ์ธ์ ๋
ธ๋ ์ค ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋ x , queue=[E]
ํ์ ๊ฐ์ฅ ์ ๋๊ธฐ์ด ๊บผ๋ด๊ธฐ
E ๋ฐฉ๋ฌธ, queue = []
E์ ์ธ์ ๋
ธ๋ ์ค ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋ x, queue =[]
queue์ ์์๊ฐ ์์ผ๋ฉด ์ข
๋ฃ.
const assert = require('assert')
/**
* TimeComplexity
* @param {*} graph
* @param {*} start
* @returns
*/
function solution(graph, start) {
const adjList = {}
graph.forEach(([from, to]) =>
adjList[from] ? adjList[from].push(to) : (adjList[from] = [to]),
)
const queue = [start]
const result = [start] //๋ฐฉ๋ฌธํ ๋
ธ๋ ๋ด๋ ๋ฐฐ์ด, bfs์์๋ queue์ ์๋ ๋
ธ๋๋ ์ด๋ฏธ ๋ฐฉ๋ฌธ์ฒ๋ฆฌ ์๋ฃ.
bfs(queue)
return result
function bfs() {
while (queue.length) {
const nextList = adjList[queue.shift()]
;(nextList || []).forEach((next) => {
if (result.includes(next)) return false //์ด๋ฏธ ๋ฐฉ๋ฌธํ ๋
ธ๋๋ฉด continue
result.push(next) //๋ฐฉ๋ฌธ์ฒ๋ฆฌ
queue.push(next) //๋ฐฉ๋ฌธ์ฒ๋ฆฌ
})
}
}
}
assert.deepEqual(
solution(
[
[1, 2],
[1, 3],
[2, 4],
[2, 5],
[3, 6],
[3, 7],
[4, 8],
[5, 8],
[6, 9],
[7, 9],
],
1,
),
[1, 2, 3, 4, 5, 6, 7, 8, 9],
)
assert.deepEqual(
solution(
[
[0, 1],
[1, 2],
[2, 3],
[3, 4],
[4, 5],
[5, 0],
],
1,
),
[1, 2, 3, 4, 5, 0],
)
DFS์ BFS์ interchangeable ํ๊ฐ?
์ค๋ ์คํฐ๋์ฅ๋์ ์ง๋ฌธ์ด ์์๋๋ฐ DFS์ BFS๋ interchangeable ํ๊ฐ ์๋ค. ์๋ฆฌ๋ฅผ ์ ๋๋ก ์ดํดํ๊ณ ์์ง ๋ชปํ๋ ๋ต์ ํ ์ ์์๋ค. ๊ณต์ ํด ์ฃผ์ ์๋ฃ Stack-based graph traversal โ depth first search์ ๋ค์ ์ฝ์ด ๋ณด์๋ค. ์๋ฌธ์ ์๋์ ์ ๋ฒ์ญ๊ณผ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์ด ๋ถ๋ถ์ ๋ํด ๋ค๋ฅธ ์๊ฐ์ด๋ ํ๋ฆฐ ๋ถ๋ถ์ด ์๋ค๋ฉด ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
์ฒ์ ๋์ ์๊ฐ์ BFS์ ํ ๋ฐฉ์์ ์คํ์ผ๋ก ๋ฐ๊ฟ ๊ตฌํํ๋ฉด ์คํ์ผ๋ก ๋ถํฐ ๋์จ ๋ ธ๋์ ์ธ์ ๋ ธ๋๋ค ์ค ๋ฐฉ๋ฌธํ์ง ์์ ๋ ธ๋๋ค์ ์คํ์ ๋ฃ๊ณ ๋ค์ ์ํ์์ ์ต๊ทผ ๋ ธ๋๋ฅผ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ฐ๋ณตํ๋ฉด DFS๋ก ๊ฐ๋ฅํ์ง ์์๊น๊ฐ ๋ด ์๊ฐ์ด์๋ค.
์ด ๊ธ์์ ๋ด ์๊ฐ์ด ํ๋ ธ์์ ๋ฐ์ฆํด์ค๋ค. ์ด ์ฝ๋๋ bfs์ queue๋ฅผ stack์ผ๋ก ๋ณ๊ฒฝํ ์ฝ๋ ์ด๋ค. stack์ผ๋ก ๋ณ๊ฒฝ๋์์ผ๋ ์ผํ dfs๊ฐ ๋์ง ์์๊น ํ์ง๋ง ์๋ ์ด๋ฏธ์ง์ฒ๋ผ input์ด ์ฃผ์ด์ก์ ๋, ์ค์ dfs์ฝ๋๋ s-a-b-e-d-c-f-g-h-e-g ์ด๋ฐ ๋ฐฉ์์ผ๋ก ๊ฐ์ผ ํ๋๋ฐ, stack traversal ํจ์๋ฅผ ์ ์ฉํ๋ฉด dfs๋ bfs๋ ์๋ ๋ฐฉ์์ผ๋ก ํ์์ด ๋๋ค.
์๊ธ์์ ํธ๋ฆฌ๋ AI research context์์ ์ค๋ณต ๊ฒ์ฌ๋ฅผ ํ์ง ์๋ ๊ฒฝ์ฐ๋ ์ค์ DFS ํ์์ ํ๋ค๊ณ ํ๋ค. ํ์ง๋ง ์ผ๋ฐ์ ๋ฐฉ๋ฌธ ์ฌ๋ถ๋ฅผ ๊ฐ์ง ๊ทธ๋ํ์์๋ DFS ํ์์ด ์๋๋ผ๊ณ ํ๋ค. ์ด๋ ๊ฒ ๋๋ ์ด์ ๊ฐ ์ฝ๋์์ ์ฒ๋ผ ์ธ์ ๋ ธ๋๋ฅผ ์คํ์ ๋จผ์ ๋ฃ๋ค ๋ณด๋, DFS์์ ๋งํ๋ ๋ถ๋ชจ-์์์ ๊ด๊ณ๋ก ๋๊น์ง ํ์ํ๋ ๊ณผ์ ์ด ์ด๋ฃจ์ด ์ง์ง ์๋๋ค.
def stack_traversal(G,s):
visited = {s}
stack = [s]
while stack:
v = stack.pop()
for w in G[v]:
if w not in visited:
visited.add(w)
stack.append(w)
์ด์ ๋ํ ์คํ์ ์ด์ฉํ ๋ฐฉ๋ฒ์ผ๋ก DFS๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์ , ํ์ฌ ๋ ธ๋์์ ์ธ์ ๋ ธ๋๋ฅผ ์คํ์ ๋ฃ๋ ๊ฒ์ด ์๋, ์ธ์ ๋ ธ๋๋ฅผ ๋ฐฉ๋ฌธ ํ๊ณ ๋์ ๋ฃ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝ ํ์ฌ DFS ๋ฅผ ๊ตฌํํ๋ค.
def dfs2(G,s):
visited = set()
stack = [s]
while stack:
v = stack.pop()
if v not in visited:
visited.add(v)
for w in G[v]:
stack.append(w)
iterator๋ฅผ ์ด์ฉํ ๋ค๋ฅธ ๋ฐฉ๋ฒ๋ ์ ์ํ๋ค.
def dfs(G,s):
visited = {s}
stack = [iter(G[s])]
while stack:
try:
w = stack[-1].next()
if w not in visited:
visited.add(w)
stack.append(iter(G[w]))
except StopIteration:
stack.pop()
์์ ๋๊ฐ์ง ๋ฐฉ๋ฒ์ ์๋ก ์ํ ์์๋ ๋ค๋ฅด์ง๋ง DFS ๊ตฌํ์ ์์ด์ ์ถฉ๋ถํ๋ฉฐ, ์ฒซ๋ฒ์งธ ๋ฐฉ์์ด ์ค๋ณต์ผ๋ก ์ธํด ๋ ๋ง์ ๊ณต๊ฐ์ ์ฐจ์ง ํ์ง๋ง dfs์์ ๋๋ค ์ ํจํ ํ์์ด๋ค.
๊ทธ๋ํ ์ต๋จ ๊ฒฝ๋ก ๊ตฌํ๊ธฐ
๋ค์ต์คํธ๋ผ์ ๋ฒจ๋ง-ํฌ๋ ์๊ณ ๋ฆฌ์ฆ ์ฐจ์ด
๋ชฉ์ | ์ฅ๋จ์ ๋ฐ ํน์ง | ์๊ฐ ๋ณต์ก๋ | |
---|---|---|---|
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ | ์ถ๋ฐ ๋ ธ๋๋ก๋ถํฐ ๋์ฐฉ ๋ ธ๋๋ค๊น์ง์ ์ต๋จ๊ฒฝ๋ก ์ฐพ๊ธฐ | ์์ ๊ฐ์ค์น๋ฅผ ๊ฐ์ง๋ ๊ทธ๋ํ์์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ ์ ์์(๊ทธ๋ฆฌ๋ ๋ฐฉ์) | O(V^2), ์ฐ์ ์์ํ ์ ๊ฒฝ์ฐ O(E*logV) |
๋ฒจ๋ง-ํฌ๋ ์๊ณ ๋ฆฌ์ฆ | ์ถ๋ฐ๋ ธ๋๋ก๋ถํฐ ๋์ฐฉ ๋ ธ๋๋ค๊น์ง์ ์ต๋จ ๊ฒฝ๋ก ์ฐพ๊ธฐ | ์์ ๊ฐ์ค์น๋ฅผ ๊ฐ์ง๋ ๊ทธ๋ํ์์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๊ตฌํ ์ ์๊ณ , ์์ ์ํ๋ ๊ฐ์งํ ์ ์์ | O(V*E) |
๋ค์ต์คํธ๋ผ ๊ตฌํ ๋ฐฉ๋ฒ
- ๊ฑฐ๋ฆฌ ํ ์ด๋ธ ์ด๊ธฐํ,
- ๊ฒฝ๋ก ํ ์ด๋ธ ์ด๊ธฐํ (๋ฌธ์ ์ ๋ฐ๋ผ ์ต์ ํ๋ ๊ฒฝ๋ก ์ถ๋ ฅ์ด ํ์ํ ์)
- ์ฐ์ ์์ํ ์ด๊ธฐํ
- ํ๋ด์ ์์๊ฐ ์๋ค๋ฉด,
- ๊ฐ์ฅ ์งง์ ๊ฑฐ๋ฆฌ์ ๊ฐ์ ๊ฐ์ง๊ณ ์๋ ์์๋ฅผ ๊ฐ์ ธ์จ๋ค.
- ๋ง์ฝ ํ์ฌ ๋ ธ๋์ ๊ฑฐ๋ฆฌ ๊ฐ์ด ํ์์ ๊ฐ์ ธ์จ ๊ฑฐ๋ฆฌ๊ฐ๋ณด๋ค ํฌ๋ฉด, ํด๋น๋ ธ๋๋ ์ด๋ฏธ ์ฒ๋ฆฌ๋ ๊ฒ์ผ๋ก ๊ฐ์ฃผ ํ๊ณ ๋ค์ iteration์ ์งํํ๋ค.
- ์๋๋ผ๋ฉด, ํ์ฌ ๋ ธ๋์ ์ธ์ ํ ๋ ธ๋๋ค์ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ์ฐํ์ฌ ์ ๋ฐ์ดํธ
const assert = require('assert')
const { PriorityQueue } = require('../utils/PriorityQueue')
function solution(graph, start) {
//distance
let distances = {}
Object.keys(graph).forEach((v) => (distances[v] = Infinity))
//paths
const paths = { [start]: [start] }
//heap
const pq = new PriorityQueue()
//์ถ๋ฐ ๊ฑฐ๋ฆฌ ์ด๊ธฐํ
distances[start] = 0
// heap ์ฒ์ ์ด๊ธฐํ
pq.enqueue(0, start)
while (pq.values.length > 0) {
let { val: currentW, priority: currentV } = pq.dequeue()
if (distances[currentV] < currentW)
continue //ํ์ฌ distance๊ฐ ๋ ์์ผ๋ฉด continue
//์ธ์ ๋ฆฌ์คํธ ์ํ
;(Object.keys(graph[currentV]) || []).forEach((nextV) => {
let nextW = graph[currentV][nextV]
// ๋ค์ด๋
ธ๋ ๊ฐ์ค์น+ํ์ฌ ๋
ธ๋, ๋ค์ ๋
ธ๋ ๊ฐ์ค์น ๋น๊ต
if (currentW + nextW < distances[nextV]) {
//distance ํ
์ด๋ธ ๊ฐฑ์
distances[nextV] = currentW + nextW
//paths ํ
์ด๋ธ ๊ฐฑ์
paths[nextV] = [...paths?.[currentV], nextV]
//pq ๋ฃ๊ธฐ
pq.enqueue(currentW + nextW, nextV)
}
})
}
//ํค ๊ธฐ์ค ์ ๋ ฌ
const sortedPath = Object.keys(paths)
.sort()
.reduce((sortedObj, key) => {
sortedObj[key] = paths[key]
return sortedObj
}, {})
return [distances, sortedPath]
}
๋ฒจ๋ง-ํฌ๋ ๊ตฌํ ๋ฐฉ๋ฒ
- ๊ฐ์ ์ ๋งํผ ๋ฐ๋ณต ํ๋ฉด์
- ๊ฐ์ฃ์ง์ ์ฐ๊ฒฐ๋ ์ฃ์ง ํน์ ๋ชจ๋ ์ฃ์ง๋ฅผ ๋๋ฉด์ (๋ฌธ์ ์ ๋ฐ๋ผ)
- ์ต๋จ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐฑ์ ํ๋ค.
- 2-3๋ฒ์ ๊ฐ์ ์๋งํผ ๋ชจ๋ ์ํํ ํ, cycleํ๋ณ ์ฌ๋ถ๋ฅผ ์ํด ํ๋ฒ ๋ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ํํ๋ค. ( ์ต๋จ๊ฑฐ๋ฆฌ ๊ฐฑ์ ์ ์ธ)
const assert = require('assert')
function solution(graph, source) {
// ๊ธธ์ด ๋ฆฌ์คํธ
let distances = Array.from({ length: graph.length }, () => Infinity)
// edge ๊ธธ์ด
let edgeLen = graph.length - 1
// ๊ฒฝ๋ก ์์ ๋ฆฌ์คํธ
let sources = Array.from({ length: graph.length }, () => 'None')
// ์ถ๋ฐ ๋
ธ๋ ๊ธธ์ด 0์ผ๋ก ์ด๊ธฐํ
distances[0] = 0
// edge๊ธธ์ด ๋งํผ ์ํ
for (let i = 0; i < edgeLen; i++) {
for (let j = 0; j < graph.length; j++) {
for (const [next, w] of graph[j]) {
//infinity๊ฐ ์๋๊ณ ํ์ฌ๋
ธ๋ ๊ธธ์ด+๊ฐ์ค์น < ๋ค์ ๋
ธ๋ ๊ธธ์ด ์ด๋ฉด ๋ค์ ๋
ธ๋ ๊ธธ์ด = ํ์ฌ ๋
ธ๋ ๊ธธ์ด + ๊ฐ์ค์น ๊ฐฑ์
if (distances[j] !== Infinity && distances[j] + w < distances[next]) {
distances[next] = distances[j] + w // ์ต๋จ ๊ฑฐ๋ฆฌ ๊ฐฑ์ j->next
sources[next] = j // ๋ฐฉ๋ฌธ ๊ฒฝ๋ก ์ ์ฅ
}
}
}
}
// ์ฌ์ดํด์ธ์ง ํ์ธ
// let isCycle = false;
// edge ๊ธธ์ด ๋งํผ ์ํ
for (let j = 0; j < graph.length; j++) {
for (const [next, w] of graph[j]) {
//infinity๊ฐ ์๋๊ณ ํ์ฌ๋
ธ๋ ๊ธธ์ด+๊ฐ์ค์น < ๋ค์ ๋
ธ๋ ๊ธธ์ด ์ด๋ฉด ๋ค์ ๋
ธ๋ ๊ธธ์ด = ํ์ฌ ๋
ธ๋ ๊ธธ์ด + ๊ฐ์ค์น ๊ฐฑ์
if (distances[j] !== Infinity && distances[j] + w < distances[next]) {
return [-1]
}
}
}
return [distances, sources]
}
assert.deepEqual(
solution(
[
[
[1, 4],
[2, 3],
[4, -6],
],
[[3, 5]],
[[1, 2]],
[
[0, 7],
[2, 4],
],
[[2, 2]],
],
0,
),
[
[0, -2, -4, 3, -6],
['None', 2, 4, 1, 0],
],
)
assert.equal(
solution([
[
[1, 5],
[2, -1],
],
[[2, 2]],
[[3, -2]],
[
[0, 2],
[1, 6],
],
]),
-1,
)