[Lv2] ํ๊ฒ๋๋ฒ
function solution(numbers, target) {
var answer = 0;
function dfs(idx,sum){
if(idx<numbers.length){
dfs(idx+1,sum+numbers[idx]) //+(left)
dfs(idx+1,sum-numbers[idx]) //-(right)
}
else{ //leaf์ ๋๋ฌ
if(sum===target){ //target ์ฐพ์
answer++;
}
}
}
dfs(0,0)
return answer;
}
๐ก DFS (preorder) ์ฌ์ฉ
๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ตฌํ๊ณ , target๊ณผ sum์ด ์ผ์นํ๋ ๊ฒฝ์ฐ๋ฅผ count ํ๋ ๋ฌธ์ ์ด๋ค.
numbers์ ์ซ์๋ค์ ์ํํ๋ฉด์ +๋๋- ๋์ค์ ๊ฒฝ์ฐ๋ก ๊ฐ์ง์น๊ธฐ๋ฅผ ์งํํ๋ฉด์, ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ตฌํ๋ค.
leaf๋ ธ๋์ ๋๋ฌํ์๋, ํด๋น ์ซ์์ ์ฐ์ฐ๊ฒฐ๊ณผ์ target์ ๋น๊ตํ๋ฉด ๋๋๋ฐ,
์ฌ๊ทํจ์์ ๋ค์ด๊ฐ์ผํ ๋งค๊ฐ๋ณ์๋ idx์ sum์ด๋ค.
depth๊ฐ ์ฆ๊ฐํ ๋๋ง๋ค ์ฐ์ฐํด์ผํ ์ซ์๊ฐ ๋ฐ๋๊ธฐ ๋๋ฌธ์ idx์ sum ๊ฐ์ ๊ณ์ ์ ๋ฐ์ดํธํด์ค์ผํ๋ค.
โ +๋ฅผ ์ํ dfs(idx+1,sum+numbers[idx])์ฌ๊ท๊ฐ ๋ฐ๋ณต๋๊ณ , leaf ๋ ธ๋์ ๋๋ฌํ๋ฉด else๋ฌธ์ ์์ ์ ๋ง์น๊ณ , -๋ฅผ ์ํdfs(idx+1,sum-numbers[idx]) ์ฌ๊ท๊ฐ ์งํ๋ ๊ฒ์ด๋ค → preOrder
[Lv2] ๊ฒ์ ๋งต ์ต๋จ๊ฑฐ๋ฆฌ
function solution(maps) {
//์ต์ข
๋ชฉ์ ์ง (n,m)
let n = maps.length; // ๋งต์ ์ธ๋ก ๊ธธ์ด
let m = maps[0].length; // ๋งต์ ๊ฐ๋ก ๊ธธ์ด
let dir = [[-1, 0], [1, 0], [0, -1], [0, 1]]; // ์ด๋ํ ๋ค ๋ฐฉํฅ: ์ํ์ข์ฐ
function bfs() {
let queue = [[0, 0, 1]]; // ์์ ์ง์ (x, y) ๋ฐ ์ด๋ ๊ฑฐ๋ฆฌ
maps[0][0] = 0; // ์์์ ์ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ์ํ๋ก ํ์
while (queue.length > 0) {
let [x, y, distance] = queue.shift(); // ํ์ฌ ์์น ๋ฐ ์ด๋ ๊ฑฐ๋ฆฌ
// ๋ชฉํ ์ง์ ์ ๋๋ฌํ ๊ฒฝ์ฐ
if (x === n - 1 && y === m - 1) {
return distance; // ํ์ฌ๊น์ง์ ์ด๋ ๊ฑฐ๋ฆฌ๋ฅผ ๋ฐํ
}
// ์ํ์ข์ฐ๋ก ์ด๋ ์๋
for (const [dx, dy] of dir) {
let newX = x + dx;
let newY = y + dy;
// ์ด๋ ๊ฐ๋ฅํ ์์น์ด๊ณ , ๋ฐฉ๋ฌธํ์ง ์์ ๊ฒฝ์ฐ
if (newX >= 0 && newX < n && newY >= 0 && newY < m && maps[newX][newY] === 1) {
queue.push([newX, newY, distance + 1]); // ํ์ ์ถ๊ฐ
maps[newX][newY] = 0; // ๋ฐฉ๋ฌธํ ์์น๋ 0์ผ๋ก ๋ณ๊ฒฝํ์ฌ ์ค๋ณต ๋ฐฉ๋ฌธ ๋ฐฉ์ง
}
}
}
// ๋ชจ๋ ์์น๋ฅผ ํ์ํ ํ ๋ชฉํ ์ง์ ์ ๋๋ฌํ์ง ๋ชปํ ๊ฒฝ์ฐ
return -1;
}
return bfs();
}
๊ฐ์ฅ ์ง๊ด์ ์ด๊ณ ๋จ์ํ bfsํ์ด์ด๋ค.
ํ์นธ์ฉ ์ด๋ํ ๋๋ง๋ค ์ํ์ข์ฐ 4๊ฐ์ง ๊ฒฝ์ฐ ์ค์์ ์ํํ๋ฉด์, ์ด๋์ด ๊ฐ๋ฅํ๋ฉด ํด๋น ์์น๋ฅผ ํ์ ์ถ๊ฐํ๊ณ ์ด๋ฏธ ์จ๊ธธ์ ์ฌ๋ฐฉ๋ฌธ ํ์ง์๊ธฐ ์ํด 1์ด์๋ ๊ฐ์ ๋ฃ์ด์ค๋ค.
โ ์ด๋ฏธ ๋ฐฉ๋ฌธํ ์์น๋ 0์ผ๋ก ๋ณ๊ฒฝํ์ฌ, ์ฌ๋ฐฉ๋ฌธ์ ๋ฐฉ์งํด์ผ ํ๋ค.
์ํ์ข์ฐ ๊ฐ์ ์ฌ๋ฌ๊ฐ์ง ๊ฒฝ์ฐ๋ก ๋ป์ด๋๊ฐ ์ ์๋๋ฐ, DFS์ฒ๋ผ ๋๊น์ง ํ๋๋ง ํฌ๋ค ๋๋์ผ๋ก ํ๊ฐ์ง๋ฅผ ๋จผ์ ๋ค ํ๊ณ ์ฌ๊ทํ๋๊ฒ์ด ์๋๋ผ,
BFS๋ฅผ ํตํด ํ์นธ์ฉ ์ด๋ํ๋ฉด์ ๊ฐ๊ฐ์ ๊ฒฝ์ฐ๋ฅผ ๋ฒ๊ฐ์๊ฐ๋ฉด์ ์ด๋ํ๋ค.
โจ queue์์ ํ์ฌ์์น๋ฅผ shiftํ๊ณ ๊ทธ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๊ฐ๋ฅํ ๊ฒฝ๋ก๊ฐ์ง๋ฅผ ๋ป์ด๋๊ฐ๋ฉด์ queue์ pushํ๋ค.
๐ DFS๋ณด๋ค BFS๊ฐ ์ ํฉํ ๊ฒฝ์ฐ
→ ์ต๋จ๊ฒฝ๋ก ์ฐพ๊ธฐ๋ BFS๋ฅผ ์ฌ์ฉํ๋ฉด ์์ ๋ ธ๋๋ก๋ถํฐ ๊ฐ ๋ ธ๋๊น์ง์ ์ต๋จ ๊ฒฝ๋ก๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค. ๋ฐ๋ฉด, DFS๋ ๊ฐ๋ฅํ ํ ๊น๊ฒ ๋ ธ๋๋ฅผ ํ์ํ๊ธฐ ๋๋ฌธ์, ์ต๋จ ๊ฒฝ๋ก๋ฅผ ๋ณด์ฅํ์ง ์๋๋ค!
[Lv3] ๋คํธ์ํฌ
function solution(n, computers) {
const visited = Array.from({ length: n }, () => false);
let answer = 0;
function dfs(index) {
visited[index] = true; // ํ์ฌ ๋
ธ๋ ๋ฐฉ๋ฌธํ๋ค๊ณ ํ์
for (let j = index+1; j < n; j++) { // ๋ชจ๋ ๋
ธ๋ ์ํ
if (!visited[j] && computers[index][j]) { // ์ฒซ ๋ฐฉ๋ฌธ์ด๊ณ ์ฐ๊ฒฐ๋ ๋
ธ๋๋ฉด
dfs(j); // recursion
}
}
}
for (let i = 0; i < n; i++) {
if (!visited[i]) { // ๋ฐฉ๋ฌธํ์ง ์์ ๋
ธ๋๋ผ๋ฉด
dfs(i); // DFS ์ํํ๊ณ
answer++; // ์นด์ดํธ ์ฆ๊ฐ
}
}
return answer;
}
์ ํ์ ์ธ ๊ทธ๋ํ ๋ฌธ์ ๋ก, ๊ฐ ์ปดํจํฐ์์ ์ถ๋ฐํด์, ๊ทธ๋ํ๋ฅผ ํ์ํ๋ค๊ฐ ๋์ด์ ์ฐ๊ฒฐ๋ ์ปดํจํฐ๊ฐ ์๋ค๋ฉด ํ๋์ ๋คํธ์ํฌ๋ฅผ ๋ฐ๊ฒฌํ๊ฒ์ด๋ค.
โ ํ๋ฒ ๋ฐฉ๋ฌธํ ๋ ธ๋๋ ๋ฐฉ๋ฌธํ์ง ์๋๊ฒ ์ด ๋ฌธ์ ์ ํฌ์ธํธ๋ค. ๋ฌดํ๋ฃจํ์ ๋น ์ง์ ์์ผ๋ ์ฃผ์ํด์ผ ํ๋ค!
โ ๋ฌด๋ฐฉํฅ ๊ทธ๋ํ๋ผ๊ณ ๊ฐ์ ํ๊ธฐ ๋๋ฌธ์, A์์ B์ ์ฐ๊ฒฐ์ด ์๋ค๋ฉด, B์์ A๋ก๋ฐ๋์ ์ฐ๊ฒฐ ๋์ด์๋ค.
์ ์ฒด ๋ฐฐ์ด์ ์ํํ๋ฉด์ ๋ฐฉ๋ฌธํ์ง ์์ผ๋ฉด, DFS ํจ์๋ฅผ ์คํํ๋๋ฐ, ์ฒซ๋ฐฉ๋ฌธ&์ฐ๊ฒฐ๋ ๋ ธ๋๋ผ๋ฉด ์ฌ๊ท๋ฅผ ์งํํ๋ค.
A๊ฐ B์ ์ฐ๊ฒฐ๋์ด์๋ค๋ฉด, B๋ก ํ๋ผ๋ฏธํฐ๋ก ๋ณ๊ฒฝํด์ B์ ์ฐ๊ฒฐ๋ ์ปดํจํฐ๋ฅผ ์ฐพ๋ ๋๋์ด๋ค. ์ด๋ ๊ฒ ์ด์ด์ ์ฌ๊ท๊ฐ ๋๋๊ณ ๋๋ฉด, ์นด์ดํธ๋ฅผ ์ฆ๊ฐ์ํค๋๋ฐ ์ฌ๊ท๊ฐ ๋๋์์ ๊น์ง ๋ชจ๋ ๊ฐ์ ์ ์ผ๋ก ์ฐ๊ฒฐ๋ ํ๋์ ๋คํธ์ํฌ๋ฅผ ์ฐพ์๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ฉด๋๋ค.
๐ Refactor
class Queue {
constructor() {
this.items = {}; // ๊ฐ์ฒด๋ก ์ ์
this.head = 0;
this.tail = 0;
}
enqueue(item) {
this.items[this.tail] = item;
this.tail++;
}
dequeue() {
const item = this.items[this.head];
delete this.items[this.head];
this.head++;
return item;
}
size() {
return this.tail - this.head;
}
}
function solution(maps) {
const queue = new Queue();
const [n, m] = [maps.length, maps[0].length];
const [targetX, targetY] = [n - 1, m - 1];
const dx = [-1, 1, 0, 0]; // ์ข, ์ฐ
const dy = [0, 0, -1, 1]; // ์, ํ
queue.enqueue([0, 0, 1]); // ์์ ์์น์ ๊ฑฐ๋ฆฌ
while (queue.size() > 0) {
const [x, y, distance] = queue.dequeue();
// ์๋๋ฐฉ ์ง์ ๋์ฐฉ
if (x === targetX && y === targetY) {
return distance;
}
// ์ํ์ข์ฐ ์ด๋
for (let i = 0; i < 4; i++) {
const newX = x + dx[i];
const newY = y + dy[i];
// index ์ ํจ ๋ฒ์ ํ์ธ
if (newX < 0 || newX >= n || newY < 0 || newY >= m) continue; // newY ๋ฒ์ ์์
// 1 = ์ด๋ ๊ฐ๋ฅ
if (maps[newX][newY] === 1) {
queue.enqueue([newX, newY, distance + 1]);
maps[newX][newY] = 0; // ์ฌ๋ฐฉ๋ฌธ ๋ฐฉ์ง
}
}
}
return -1; // ๋ชฉํ์ ๋๋ฌํ ์ ์๋ ๊ฒฝ์ฐ
}
queue๋ฅผ ๋ฐฐ์ด์ด ์๋ ๊ฐ์ฒด๋ก ํ์ฉํ๋ฉด shift๋ฅผ ํตํด O(N)์ด์๋ ์๊ฐ๋ณต์ก๋๋ฅผ O(1)๋ก ๋จ์ถ์ํฌ ์ ์๋ค.
[Lv3] ๋จ์ด ๋ณํ
function solution(begin, target, words) {
let visited=[];
let queue=[];
let answer = 0;
//early return
if(!words.includes(target)) return 0;
queue.push([begin,answer]);
while(queue.length>0){
let [current,count]=queue.shift();
if(current===target){ //๋ณํ์๋ฃ
return count;
}
for(const word of words){
//๋ฐฉ๋ฌธ์ฌ๋ถ ํ์ธ
if(visited.includes(word)) continue;
//ํ๊ธ์๋ง ๋ค๋ฅธ์ง ํ์ธ
if(isOneDiff(current,word)){
//queue์ push
queue.push([word,++count]);
//๋ฐฉ๋ฌธ ๋จ๊ธฐ๊ธฐ
visited.push(word);
}
}
}
return answer;
}
function isOneDiff(word1,word2){
let differences=0;
for(let i=0;i<word1.length;i++){
if(word1[i]!==word2[i]) differences++;
}
return differences===1?true:false;
}
๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ํ์ธํ์ง ์์๋ target๋ง ์ฐพ์ผ๋ฉด ๋๊ธฐ๋๋ฌธ์, BFS๋ฅผ ์ฌ์ฉํ์๋ค.
โ current=target์ ๋๋ฌํ๋ฉด count๋ฅผ ๋ฆฌํดํ๋๋ฐ, BFS๋ ๊ฐ์ฅ ๊ฐ๊น์ด ๋ ธ๋๋ถํฐ ์ฐจ๋ก๋๋ก ํ์ํ๊ธฐ ๋๋ฌธ์ ์ฒ์์ผ๋ก target์ ๋๋ฌํ ๋จ๊ณ๊ฐ ์ต์ ๋ณํ ํ์์ด๋ค