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 |
Tags
- Vue3 Router
- react 프로젝트 리팩토링
- 머쓱이
- frontend roadmap study
- 개발자 특강
- TypeScript 문법 소개
- 인프런 자바스크립트 알고리즘 문제풀이
- 프로그래머스 K_Digital Training
- 프로그래머스 K_Digital Training 프론트엔드
- 백준 node.js
- useRef 지역 변수
- 모던 자바스크립트 TIL
- 모던 javascript Deep Dive
- Frontend Roadmap
- 프로그래머스 데브코스 프론트엔드
- 우테캠 회고록
- 리팩토링 회고
- 모던 자바스크립트 Deep Dive TIL
- 모던 자바스크립트 Deep Dive
- 모던 자바스크립트 딥다이브
- 투포인터알고리즘 js
- 프로그래머스 데브코스
- 백준 js
- KDT 프로그래머스 데브코스 프론트엔드
- KDT 프로그래머스
- useEffect return
- 프로그래머스 데브코스 프론트엔드 TIL
- react customHook 예시
- Vue3
- K_Digital Training
Archives
- Today
- Total
프론트엔드 개발자의 기록 공간
[백준 node.js] 7576번_토마토 본문
🚩 7576번_토마토 골드5
📖 문제 설명 : N x M 상자 크기에 토마토가 있을 경우, 하루가 지날 때마다 인접 토마토들을 익게 한다.
모든 토마토가 익는 데까지 걸리는 최소 일수 구하기
💡 시간 초과를 벗어나기 위해서는 queue 알고리즘을 구현해서 사용 or index가 증가하는 cursor를 두고, queue.length < queueCursor를 사용
queue 알고리즘을 구현 예시
const fs = require('fs')
const [mn, ...input] = fs
.readFileSync('/dev/stdin')
.toString()
.trim()
.split('\n')
const [m, n] = mn.split(' ').map(Number)
const graph = input.map((x) => x.split(' ').map(Number))
// JS에서 BFS 구현시 shift, push로 queue 구현
// shift 연산은 O(n)을 가지므로 시간 초과날 가능성이 높다.
// 따라서 직접 구현해서 시용
// 각각의 노드, 노드의 data와 다음 노드를 가리키고 있다.
class Node {
constructor(data) {
this.data = data
this.next = null
}
}
// 큐 클래스
class Queue {
constructor() {
this.head = null // 제일 앞 노드
this.rear = null // 제일 뒤 노드
this.length = 0 // 노드의 길이
}
enqueue(data) {
// 노드 추가.
const node = new Node(data) // data를 가진 node를 만들어준다.
if (!this.head) {
// 헤드가 없을 경우 head를 해당 노드로
this.head = node
} else {
this.rear.next = node // 아닐 경우 마지막의 다음 노드로
}
this.rear = node // 마지막을 해당 노드로 한다.
this.length++
}
dequeue() {
// 노드 삭제.
if (!this.head) {
// 헤드가 없으면 한 개도 없는 것이므로 false를 반환.
return false
}
const data = this.head.data // head를 head의 다음 것으로 바꿔주고 뺀 data를 return
this.head = this.head.next
this.length--
return data
}
}
// 인덱스 검증
function isRange(dx, dy) {
if (dx >= 0 && dy >= 0 && dx < n && dy < m) {
return true
}
return false
}
function BFS(graph, queue) {
// 상하좌우
const dx = [-1, 1, 0, 0]
const dy = [0, 0, -1, 1]
let day = 0
while (queue.length) {
let [i, j, cnt] = queue.dequeue()
for (let k = 0; k < 4; k++) {
let mx = i + dx[k]
let my = j + dy[k]
if (isRange(mx, my) && graph[mx][my] === 0) {
graph[mx][my] = 1
queue.enqueue([mx, my, cnt + 1])
}
}
day = cnt
}
let answer = day
// BFS 수행 후 0이 있을 경우 토마토가 익지 못하는 상황 발생
graph.forEach((_, i) => {
if (graph[i].includes(0)) {
answer = -1
}
})
return answer
}
function solution() {
let answer = 0
const queue = new Queue()
graph.forEach((_, i) => {
graph[i].forEach((_, j) => {
if (graph[i][j] === 1) {
queue.enqueue([i, j, 0])
}
})
})
// BFS 함수 수행하고 나면 인접 토마토가 모두 익게 된다.
answer = BFS(graph, queue)
return answer
}
console.log(solution())
index를 이용하여 해결한 예시 (이 외의 코드는 동일)
....
....
function BFS(graph, queue) {
// 상하좌우
const dx = [-1, 1, 0, 0]
const dy = [0, 0, -1, 1]
let day = 0
let index = 0
while (queue.length > index) { // index 이용
let [i, j, cnt] = queue[index++]
for (let k = 0; k < 4; k++) {
let mx = i + dx[k]
let my = j + dy[k]
if (isRange(mx, my) && graph[mx][my] === 0) {
graph[mx][my] = 1
queue.push([mx, my, cnt + 1])
}
}
....
....
👨💻 코드 설명
상자 (graph)를 돌면서 토마토의 위치 정보를 전부 queue에 저장해 준다.
queue를 가지고 흔한 BFS 알고리즘을 사용해 주면 된다. 그러면 최소한의 일수를 구할 수 있다.
사실 이 문제는 이전에 해결하지 못했었다. 예전에는 다른 블로그들을 참고해도 동일하게 queue를 사용해서 했는데 그대로 로직을 구성했지만, 시간 초과가 계속 났었다. 그래서 단순 언어적의 한 계로 풀지 않고 미뤄뒀었다.
이번에 다시 풀게 되면서 시간 초과를 해결하기 위해 queue를 구현하였고(오픈 소스), 또 다른 풀이를 통해 index로 해결하는 법을 알 수 있었다.
잘못된 설명, 코드, 예외 케이스가 있다면 댓글 남겨주시면 수정하겠습니다.
728x90
'알고리즘_JS > 백준_Graph(DFS,BFS)' 카테고리의 다른 글
[백준 node.js] 2644번_촌수계산 (0) | 2021.02.03 |
---|---|
[백준 node.js] 7562번_나이트의 이동 (0) | 2021.01.17 |
[백준 node.js] 11725번_트리의 부모 찾기 (0) | 2021.01.13 |
[백준 node.js] 2468번_안전 영역 (0) | 2021.01.11 |
[백준 node.js] 2583번_영역 구하기 (0) | 2021.01.08 |
Comments