알고리즘 풀이 시 어느정도 외워두면 편한 패턴들이 있다. 코딩테스트 합격자 되기 도서를 참고하여 작성하였으며, 자바스크립트로 코딩테스트를 준비하는 분들이라면 해당 도서를 한번 쯤 읽어 봄직하다.
// 연결리스트
class Node {
constructor(data) {
this.data = data; // 요소의 값
this.next = null; // 다음 요소를 참조
}
}
class Queue {
constructor() {
this.head = null; // 첫 번째 요소 참조
this.tail = null; // 마지막 요소 참조
this.size = 0; // 큐의 길이
}
push(data) {
// 새로운 요소를 생성
const newNode = new Node(data);
if (!this.head) {
// 큐가 비어 있다면 head와 tail을 모두 새로 생성한 요소로 설정
this.head = newNode;
this.tail = newNode;
// 아니면 현재 tail의 next 속성을 새로운 요소로 설정 후 tail이 새로운 요소를 참조하도 록 변경
} else {
this.tail.next = newNode;
this.tail = newNode;
}
this.size++; // 큐 길이 증가
}
pop() {
// head가 null이라면 비어 있다는 뜻
if (!this.head) {
return null;
}
// 두 번째 요소를 head의 참조로 변경하면
// 자연스럽게 첫 번째 요소가 사라짐
const removeNode = this.head;
this.head = this.head.next;
// 만약 두 번째 요소가 없었다면
// 큐가 비어 있다는 뜻이니 tail도 null로 설정
if (!this.head) {
this.tail = null;
}
this.size--; // 큐 길이 감소
// 삭제된 요소의 값을 반환
return removeNode.data;
}
isEmpty() {
return this.size === 0;
}
}
function binarySearch(sortedArray, target) {
let left = 0;
let right = sortedArray.length - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (sortedArray[mid] === target) {
return mid; // 찾은 경우 해당 인덱스 반환
} else if (sortedArray[mid] < target) {
left = mid + 1; // 왼쪽 포인터를 오른쪽으로 이동
} else {
right = mid - 1; // 오른쪽 포인터를 왼쪽으로 이동
}
}
return -1; // 찾지 못한 경우 -1 반환
}
// 사용 예제
const sortedArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const target = 7;
const result = binarySearch(sortedArray, target);
if (result !== -1) {
console.log(`타겟 값 ${target}은(는) 인덱스 ${result}에 있습니다.`);
} else {
console.log("타겟 값을 찾지 못했습니다.");
}
깊이 탐색한 다음 되돌아오는 깊이 우선 탐색으로, 하나의 경로를 끝까지 시도해봐야 하는 문제에서 주로 사용된다.
DFS에서 시간초과가 발생한다면 BFS를, BFS에서 메모리 초과가 발생한다면 DFS를 시도해보는 것이 좋다.
function solution(graph, start) {
const result = []
const list = {};
const visited = new Set();
for (const [a, b] of graph) {
list[a] = list[a] ? list[a].concat(b) : [b];
}
function dfs(node, visited, result) {
visited.add(node);
result.push(node);
(list[node] || []).forEach((neighbor) => {
if (!visited.has(neighbor)) {
dfs(neighbor, visited, result);
}
});
}
dfs(start, visited, result);
return result;
}
넓게 탐색하며 진행하는 너비 우선 탐색으로, 최단거리를 찾아야 하는 문제에서 주로 사용된다.
/** 넓이 우선탐색 */
function solution(graph, start) {
const result = [start]
const list = {};
const visited = new Set();
for (const [a, b] of graph) {
list[a] = list[a] ? list[a].concat(b) : [b];
}
const queue = [];
queue.push(start);
visited.add(start);
while (queue.length) {
const node = queue.shift();
for (const target of list[node] || []) {
if (!visited.has(target)) {
queue.push(target);
visited.add(target);
result.push(target);
}
}
}
console.log(result)
return result;
}