From 9de9ea2531ec84c2bb5cf4b5ca45d1c1b3db3960 Mon Sep 17 00:00:00 2001 From: youngduck Date: Thu, 28 May 2026 17:19:30 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=EB=B8=94=EB=A1=9C=EA=B7=B8=EC=98=A4?= =?UTF-8?q?=ED=83=88=EC=9E=90=EC=88=98=EC=A0=95-=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=EB=B0=B1=ED=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leet-98.md" | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git "a/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-98.md" "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-98.md" index 67ccb48..5556730 100644 --- "a/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-98.md" +++ "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-98.md" @@ -18,18 +18,14 @@ ogImage: **예시 1** -``` -Input: root = [2,1,3] -Output: true -``` +입력: root = [2,1,3] +출력: true **예시 2** -``` -Input: root = [5,1,4,null,null,3,6] -Output: false +입력: root = [5,1,4,null,null,3,6] +출력: false 설명: 루트의 오른쪽 자식 4가 루트보다 작으므로 BST 조건 위반 -``` **제약 조건** From 876022a26125a4cee7f7198d8bf0534a49f8f6f7 Mon Sep 17 00:00:00 2001 From: youngduck Date: Thu, 28 May 2026 17:21:07 +0900 Subject: [PATCH 2/3] =?UTF-8?q?posting:=2020260528=EC=95=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=EC=A6=98=ED=92=80=EC=9D=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../leet-206.md" | 162 ++++++++++++++++++ .../leet-206/1.png" | Bin 0 -> 29643 bytes .../leet-206/2.png" | Bin 0 -> 18080 bytes 3 files changed, 162 insertions(+) create mode 100644 "_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206.md" create mode 100644 "public/assets/algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206/1.png" create mode 100644 "public/assets/algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206/2.png" diff --git "a/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206.md" "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206.md" new file mode 100644 index 0000000..cadb99d --- /dev/null +++ "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206.md" @@ -0,0 +1,162 @@ +--- +title: "[리트코드] Reverse Linked List 자바스크립트 풀이" +excerpt: "알고리즘 재활훈련 - 연결리스트" +coverImage: "/assets/algorithms/JS-리트코드/cover.png" +date: "2026-05-27T10:53:00" +ogImage: + url: "/assets/algorithms/JS-리트코드/cover.png" +--- + +## 문제 + +단일 연결 리스트(singly linked list)의 head가 주어질 때, 리스트를 뒤집은 후 그 head를 반환하는 문제입니다. +[문제출처](https://leetcode.com/problems/reverse-linked-list/) + +**예시 1:** + +입력: head = [1,2,3,4,5] +출력: [5,4,3,2,1] + +![reverse-linked-list-1](/assets/algorithms/JS-리트코드/leet-206/1.png) + +  +**예시 2:** + +입력: head = [1,2] +출력: [2,1] + +![reverse-linked-list-2](/assets/algorithms/JS-리트코드/leet-206/2.png) +  +**예시 3:** + +입력: head = [] +출력: [] + +## 내풀이 1차 + +### 접근: 일단 단순무식하게 구현 + +### 코드 + +```javascript +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var reverseList = function (head) { + // input값 없을때 처리 + if (!head) { + return head; + } + + // 배열로 평탄화 후 다시 연결리스트 생성 + let current = head; + let arr = []; + while (current) { + arr.push(current.val); + current = current.next; + } + + let newHead = null; + + for (let i = 0; i < arr.length; i++) { + newHead = new ListNode(arr[i], newHead); + } + + return newHead; +}; +``` + +### 복잡도 + +- 시간 복잡도: O(n) — 노드 n개를 한 번 순회해 배열에 넣고, 배열을 한 번 더 순회해 리스트를 만듦 (총 2n이지만 계수는 상수) +- 공간 복잡도: O(n) — 값을 담는 배열 arr가 O(n), 새로 만드는 ListNode도 n개라 O(n) + +## 내풀이 2차 + +### 접근: 같은 O(n)인데 n계수줄일수있음 + +### 코드 + +```javascript +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var reverseList = function (head) { + // input값 없을때 처리 + if (!head) { + return head; + } + + // 최적화 : 조회하자마자 바로넣으면 뒤집어짐 + let current = head; + let newHead = null; + + while (current) { + newHead = new ListNode(current.val, newHead); + current = current.next; + } + + return newHead; +}; +``` + +### 복잡도 + +- 시간 복잡도: O(n) — current로 리스트를 한 번만 순회하며 prepend (1차 대비 순회 횟수·상수 계수 감소) +- 공간 복잡도: O(n) — 보조 배열은 없지만 새 ListNode를 n개 생성 (포인터 변수 current, newHead만 보면 O(1), 노드 할당까지 포함하면 O(n)) + +## 인터넷풀이 : 재귀 + +### 접근: 끝까지 내려가서 돌아오며 포인터 뒤집기 + +- 베이스 케이스: head가 null이거나, head.next가 null(마지막 노드)이면 그대로 반환 +- 재귀 호출: head.next부터 뒤집어서, 뒤집힌 리스트의 새로운 head를 받음 +- 포인터 재연결: + - head.next.next = head (다음 노드가 현재 노드를 가리키도록 뒤집기) + - head.next = null (현재 노드가 앞으로 새지 않게 끊기) +- 최종 반환: 재귀에서 받은 newHead(뒤집힌 리스트의 head) 이걸 그대로 출력하면됨 + +### 코드 + +```javascript +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var reverseList = function (head) { + if (!head || !head.next) return head; + + const newHead = reverseList(head.next); + head.next.next = head; + head.next = null; + return newHead; +}; +``` + +### 복잡도 + +- 시간 복잡도: O(n) — 각 노드를 한 번씩 방문 +- 공간 복잡도: O(n) — 재귀 호출 스택이 최대 n까지 쌓임 (추가 노드를 생성하지는 않음) diff --git "a/public/assets/algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206/1.png" "b/public/assets/algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-206/1.png" new file mode 100644 index 0000000000000000000000000000000000000000..ca4afd4eda5f4f302b763948554f152687f805a2 GIT binary patch literal 29643 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

ihPBx-$~uQvq+pLGm>cjJ4&s=6Fg=Aej} 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 YFZZ8{&*w9F;438Ov~2 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 Lt4P&Kn1=peS5qvB literal 0 HcmV?d00001 From f2e12e2e54ab52a3e386450f672e80e3f11b5c9f Mon Sep 17 00:00:00 2001 From: youngduck Date: Thu, 28 May 2026 17:27:31 +0900 Subject: [PATCH 3/3] =?UTF-8?q?posting:=20=EB=AC=B8=EC=A0=9C=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=ED=8C=A8=ED=84=B4=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../problem-solving-patterns.md" | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 "_algorithms/JS-\354\236\220\353\243\214\352\265\254\354\241\260/problem-solving-patterns.md" diff --git "a/_algorithms/JS-\354\236\220\353\243\214\352\265\254\354\241\260/problem-solving-patterns.md" "b/_algorithms/JS-\354\236\220\353\243\214\352\265\254\354\241\260/problem-solving-patterns.md" new file mode 100644 index 0000000..d688560 --- /dev/null +++ "b/_algorithms/JS-\354\236\220\353\243\214\352\265\254\354\241\260/problem-solving-patterns.md" @@ -0,0 +1,158 @@ +--- +title: "Problem Solving Patterns - 문제 해결 패턴 요약" +excerpt: "문제해결 패턴 정리" +coverImage: "/assets/algorithms/JS-자료구조/cover.png" +date: "2026-05-28T11:22:00" +ogImage: + url: "/assets/algorithms/JS-자료구조/cover.png" +--- + +> Colt Steele의 JavaScript Algorithms and Data Structures Masterclass 강의를 보고 “문제 해결 패턴”부분을 정리한 글입니다. + +  + +## 문제 해결 기본 루틴 + +- **문제 이해**: 입력/출력, 예외 케이스, 제약(시간/공간) 이해하기 +- **예시로 검증**: 작은 입력으로 손으로 따라가며 기대 결과 확인 +- **단순화**: 큰 문제를 더 작은 문제로 쪼개서 먼저 해결 (가장 쉬운 버전부터) +- **핵심 포인트 찾기**: 반복되는 연산, 중복 계산, “한 번만 보면 되는 정보”가 있는지 확인 +- **리팩터링**: 불필요한 루프/중첩 제거, 변수명/가독성 정리, 엣지 케이스 재확인 + +  + +## 1) 빈도수 세기 (Frequency Counter) + +- **언제**: 순서보다 “구성/개수”가 중요한 문제(애너그램, 두 배열의 관계, 중복 검증 등) +- **핵심**: Map/Object에 빈도 누적 후 비교 → 보통 **중첩 루프를 선형으로 줄임** +- **복잡도**: 시간 O(n), 공간 O(n) (알파벳 고정이면 사실상 O(1)) + +  + +## 2) 다중 포인터 (Multiple Pointers) + +- **언제**: 정렬된 배열/리스트에서 “쌍/구간/조건 만족”을 찾을 때(투포인터) +- **핵심**: left/right 포인터를 움직이며 탐색 범위를 줄임 +- **복잡도**: 보통 시간 O(n), 공간 O(1) + +  + +## 3) 슬라이딩 윈도우 (Sliding Window) + +- **언제**: “연속된 구간”의 합/최대/최소(고정 길이 또는 가변 길이) +- **핵심**: 윈도우를 한 칸씩 이동하며 이전 계산을 재사용 (누적합/카운트 갱신) +- **복잡도**: 보통 시간 O(n), 공간 O(1)~O(n) (윈도우 상태 저장 방식에 따라) + +  + +## 4) 분할 정복 (Divide and Conquer) + +- **언제**: 정렬된 데이터에서 탐색 범위를 반씩 줄일 수 있을 때(이진 탐색류) +- **핵심**: 매 단계마다 문제 크기를 절반으로 줄임 +- **복잡도**: 시간 O(log n) 또는 O(n log n) (문제에 따라) + +  + +## 5) 동적 계획법 (Dynamic Programming) + +- **언제**: 큰 문제를 작은 문제로 쪼갤 수 있고, 같은 하위 문제가 반복될 때(피보나치, 계단, 최적화 문제 등) +- **핵심**: + - **메모이제이션(Memoization)**: 탑다운(재귀) + 캐시로 이미 구한 값을 저장 + - **타뷸레이션(Tabulation)**: 보텀업(반복)으로 “테이블(배열/객체)”을 작은 값부터 채워가며 계산 +- **복잡도**: 보통 시간 O(n)~O(nm), 공간 O(n) (상태 정의에 따라) + +  + +## 6) 그리디 (Greedy) + +- **언제**: “지금 최선” 선택이 전체 최적해로 이어질 때(증명/근거가 있는 문제) +- **핵심**: 매 단계 로컬 최적 선택 +- **복잡도**: 문제에 따라 O(n), O(n log n) (정렬이 들어가면 로그 항이 붙음) + +  + +## 7) 스택/큐/덱 (Stack / Queue / Deque) + +- **언제**: + - 스택: 괄호 검사, 되돌리기/취소(undo), “이전 상태”를 기억해야 할 때 + - 큐: 순서대로 처리(BFS), 작업 대기열 + - 덱: 앞/뒤 양쪽에서 넣고 빼야 할 때 (슬라이딩 윈도우 최적화에도 등장) +- **핵심**: “LIFO/FIFO/양방향”이라는 자료구조 규칙으로 흐름을 강제해서 문제를 단순화 +- **복잡도**: 보통 시간 O(n), 공간 O(n) (저장하는 원소 수에 비례) + +  + +## 8) 그래프 탐색 (Traversal: BFS / DFS) + +- **언제**: 연결 관계가 있는 구조(그래프/격자/트리)에서 “도달 가능/최단 거리(무가중치)/영역 개수” 등을 구할 때 +- **핵심**: + - DFS: 깊게 들어갔다가 되돌아오며 탐색 (재귀/스택) + - BFS: 레벨 순서로 넓게 탐색 (큐) → 무가중치 최단거리에서 자주 사용 + - 방문 처리(visited)가 핵심 (중복 방문/무한 루프 방지) +- **복잡도**: 시간 O(V + E), 공간 O(V) (visited/queue/stack) + +  + +## 9) 이분 탐색 (Binary Search / Parametric Search) + +- **언제**: + - 정렬된 배열에서 특정 값/경계를 빠르게 찾을 때 + - “조건을 만족하는 최소/최대값”을 찾는 결정 문제(파라메트릭 서치) +- **핵심**: 정답(또는 탐색 구간)을 반으로 줄여가며 범위를 좁힘 +- **복잡도**: 시간 O(log n) (보통), 공간 O(1) + +  + +## 10) 백트래킹 / 완전탐색 (Backtracking / Brute Force) + +- **언제**: 경우의 수를 직접 탐색해야 하는데, 가지치기(조건)로 줄일 수 있을 때 (순열/조합, 선택/비선택) +- **핵심**: “선택 → 재귀 → 복원(undo)” 패턴 + 불가능한 분기는 빨리 중단(pruning) +- **복잡도**: 보통 매우 큼(지수/팩토리얼). 다만 pruning이 성능을 좌우 + +  + +## 11) 문자열 패턴 (String Patterns) + +- **언제**: 문자열 비교/변환/검증/파싱이 핵심인 문제 (애너그램, 회문, 토큰화 등) +- **핵심**: 투포인터, 빈도수 세기, 슬라이딩 윈도우, 파싱(상태 머신처럼) 조합이 자주 등장 +- **복잡도**: 보통 시간 O(n), 공간 O(1)~O(n) (추가 버퍼/맵 사용 여부) + +  + +## 12) 유니온 파인드 (Disjoint Set Union, DSU) + +- **언제**: “서로소 집합”을 관리하며 연결/그룹 여부를 빠르게 판단해야 할 때 (네트워크, 그룹 묶기) +- **핵심**: find(대표 찾기) + union(합치기), 경로 압축/랭크 최적화 +- **복잡도**: 거의 O(1)에 가까움(아커만 역함수 수준). 실전에서는 보통 O(α(n))로 표기 + +  + +## 13) 최단거리(가중치) (Dijkstra 기본) + +- **언제**: 가중치가 0 이상인 그래프에서 최단 거리를 구할 때 +- **핵심**: 우선순위 큐로 “가장 짧은 거리 후보”부터 확정해 나감 +- **복잡도**: 보통 O((V + E) log V) (우선순위 큐 사용) + +  + +## 14) 정렬 활용 (Sorting as a Strategy) + +- **언제**: “정렬하면 규칙이 생겨서” 투포인터/그리디/이분탐색이 가능해지는 문제 +- **핵심**: 정렬 자체가 목적이 아니라, 정렬 후에 문제 구조가 단순해지는지를 먼저 판단 +- **복잡도**: 보통 O(n log n) (정렬이 지배) + +  + +## 요약 + +- **구성/개수/중복**이 핵심이면 → 빈도수 세기(해시) +- **정렬되어 있고 양끝/쌍/조건**을 찾으면 → 다중 포인터 +- **연속 구간(부분 배열/substring) 최적화**면 → 슬라이딩 윈도우 +- **정답이 “최솟값/최댓값/경계값”이고 단조성**이 보이면 → 이분 탐색 / 파라메트릭 서치 +- **연결 관계/격자에서 도달/영역 개수**면 → DFS/BFS +- **무가중치 최단거리**면 → BFS +- **가중치(0 이상) 최단거리**면 → 다익스트라 +- **선택을 되돌리며 경우의 수를 탐색**해야 하면 → 백트래킹 +- **중복되는 하위 문제 + 최적화/경우의 수**면 → DP +- **그때그때 최선 선택이 맞는 문제**면 → 그리디 (정렬이 같이 붙는 경우 많음) +- **서로 연결/그룹 여부를 빠르게 판단**해야 하면 → 유니온 파인드(DSU)