diff --git "a/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-200.md" "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-200.md" new file mode 100644 index 0000000..59540ab --- /dev/null +++ "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-200.md" @@ -0,0 +1,107 @@ +--- +title: "[리트코드] Number of Islands 자바스크립트 풀이" +excerpt: "알고리즘 재활훈련 - 그래프 탐색" +coverImage: "/assets/algorithms/JS-리트코드/cover.png" +date: "2026-06-01T20:00:00" +ogImage: + url: "/assets/algorithms/JS-리트코드/cover.png" +--- + +## 문제 + +m x n 크기의 2차원 이진 그리드 grid가 주어집니다. grid는 '1'(땅)과 '0'(물)로 이루어진 지도를 나타냅니다. + +섬의 개수를 반환하세요. + +섬은 물에 둘러싸여 있으며, 가로 또는 세로로 인접한 땅들을 연결해 형성됩니다. 그리드의 네 변은 모두 물로 둘러싸여 있다고 가정해도 됩니다. + +[문제출처](https://leetcode.com/problems/number-of-islands/) + +**예시 1:** + +입력: grid = [ +["1","1","1","1","0"], +["1","1","0","1","0"], +["1","1","0","0","0"], +["0","0","0","0","0"] +] +출력: 1 + +  + +**예시 2:** + +입력: grid = [ +["1","1","0","0","0"], +["1","1","0","0","0"], +["0","0","1","0","0"], +["0","0","0","1","1"] +] +출력: 3 + +  + +**제약 조건:** + +- m == grid.length +- n == grid[i].length +- 1 <= m, n <= 300 +- grid[i][j]는 '0' 또는 '1'이다. + +## 내풀이 + +### 접근: 이중 for문 + DFS(재귀)로 연결된 땅 제거 + +- grid 전체를 이중 for문으로 순회 +- "1"을 만나면 새로운 섬 → result += 1 +- recursive로 상하좌우 탐색하며 연결된 "1"을 "0"으로 바꿈 (visited 대신 grid 자체를 수정) +- 경계 밖(row/col < 0 또는 >= end)이면 return + +  + +### 코드 + +```javascript +/** + * @param {character[][]} grid + * @return {number} + */ +var numIslands = function (grid) { + let result = 0; + const end_row = grid.length; + const end_col = grid[0].length; + + const recursive = (row, col) => { + if (row < 0 || row >= end_row || col < 0 || col >= end_col) { + return; + } + + // 재귀 타면서 연결된 땅은 0으로 변환 → for문에서 같은 섬을 다시 세지 않도록 + if (grid[row][col] === "1") { + grid[row][col] = "0"; + recursive(row - 1, col); + recursive(row, col - 1); + recursive(row + 1, col); + recursive(row, col + 1); + } + }; + + for (let m = 0; m < grid.length; m++) { + for (let n = 0; n < grid[0].length; n++) { + if (grid[m][n] === "1") { + recursive(m, n); + result += 1; + } + } + } + + return result; +}; +``` + +  + +### 복잡도 + +- 시간 복잡도: O(m × n) — 각 칸을 최대 1번 방문 +- 공간 복잡도: O(m × n) — 재귀 호출 스택 (최악: 섬이 한 줄로 길게 이어질 때) diff --git "a/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-62.md" "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-62.md" new file mode 100644 index 0000000..46d2507 --- /dev/null +++ "b/_algorithms/JS-\353\246\254\355\212\270\354\275\224\353\223\234/leet-62.md" @@ -0,0 +1,127 @@ +--- +title: "[리트코드] Unique Paths 자바스크립트 풀이" +excerpt: "알고리즘 재활훈련 - 동적 계획법" +coverImage: "/assets/algorithms/JS-리트코드/cover.png" +date: "2026-06-01T19:40:00" +ogImage: + url: "/assets/algorithms/JS-리트코드/cover.png" +--- + +## 문제 + +m x n 크기의 격자가 있습니다. 로봇은 처음에 **왼쪽 위 모서리 (0, 0)** 에 있습니다. 로봇은 **오른쪽 아래 모서리 (m - 1, n - 1)** 로 이동하려고 합니다. + +로봇은 한 번에 **아래** 또는 **오른쪽**으로만 이동할 수 있습니다. + +정수 m, n이 주어질 때, 로봇이 오른쪽 아래 모서리에 도달할 수 있는 **서로 다른 경로의 수**를 반환하세요. + +[문제출처](https://leetcode.com/problems/unique-paths/description/) + +**예시 1:** + +입력: m = 3, n = 7 +출력: 28 + +  + +**예시 2:** + +입력: m = 3, n = 2 +출력: 3 + +설명: 왼쪽 위에서 오른쪽 아래까지 가는 방법은 총 3가지입니다. + +1. 오른쪽 → 아래 → 아래 +2. 아래 → 아래 → 오른쪽 +3. 아래 → 오른쪽 → 아래 + +  + +**제약 조건:** + +- 1 <= m, n <= 100 + +## 내풀이 1차 + +### 접근: 조합 + +문제를 읽고 확률과통계가 딱떠올랐다. +오랜만이라 기억이 가물가물한데 조합방식으로 풀면 문제가 해결되겠다고 생각이 들었다. +m x n 격자에서 (0,0) → (m-1, n-1)까지 가려면 총 이동 횟수는 언제나 동일하기 때문에 + +- 아래로 가야 하는 횟수: m - 1 +- 오른쪽으로 가야 하는 횟수: n - 1 +- 총 이동 횟수: m + n - 2 + +예시 1 (m=3, n=7)일때 **아래 2번, 오른쪽 6번**을 **어떤 순서로 섞을지**만 생각 해주면 되는 문제다. +즉 RRRRRRDD, RRRRRDRD, … 처럼 **8칸짜리 줄에서 2개의 위치를 고르는 것**과 같다. + +  + +### 코드 + +```javascript +/** + * @param {number} m + * @param {number} n + * @return {number} + */ +var uniquePaths = function (m, n) { + const factorial = (num) => { + if (num <= 1) { + return 1; + } + return num * factorial(num - 1); + }; + + return factorial(m + n - 2) / (factorial(n - 1) * factorial(m - 1)); +}; +``` + +  + +### 복잡도 + +- 시간 복잡도: O(m + n) — factorial을 3번 호출하며, 가장 큰 인자 m + n - 2 기준으로 재귀 깊이만큼 연산 +- 공간 복잡도: O(m + n) — factorial 재귀 호출 스택 (최대 m + n - 2까지 쌓임) + +## 내풀이 2차 + +### 접근: 동적 계획법 (2차원 DP) + +특정 칸 (i, j)에 도달하는 경로 수는 **위에서 오는 경로 + 왼쪽에서 오는 경로**의 합이다. + +- dp[i][j]: (i, j)에 도달하는 서로 다른 경로의 수 +- 점화식: dp[i][j] = dp[i - 1][j] + dp[i][j - 1] +- 초기값: 첫 행·첫 열은 오른쪽/아래만 갈 수 있으므로 모두 1 +- 답: dp[m - 1][n - 1] + +  + +### 코드 + +```javascript +/** + * @param {number} m + * @param {number} n + * @return {number} + */ +var uniquePaths = function (m, n) { + const dp = Array.from({ length: m }, () => Array(n).fill(1)); + + for (let i = 1; i < m; i++) { + for (let j = 1; j < n; j++) { + dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; + } + } + + return dp[m - 1][n - 1]; +}; +``` + +  + +### 복잡도 + +- 시간 복잡도: O(m × n) — 격자 전체를 한 번씩 채움 +- 공간 복잡도: O(m × n) — dp 2차원 배열 (1차원 배열로 줄이면 O(n)까지 가능) diff --git a/_algorithms/SQLD/sqld-1.md b/_algorithms/SQLD/sqld-1.md new file mode 100644 index 0000000..fb31fa1 --- /dev/null +++ b/_algorithms/SQLD/sqld-1.md @@ -0,0 +1,206 @@ +--- +title: "[SQLD] 1장. 데이터 모델링의 이해" +excerpt: "데이터 모델의 이해, 엔터티, 속성, 관계, 식별자" +coverImage: "/assets/blog/posts/mysql/cover.png" +date: "2026-06-08T21:00:00" +ogImage: + url: "/assets/blog/posts/mysql/cover.png" +--- + +## 1.1 데이터 모델의 이해 + +### 모델링이란 + +- 현실세계의 데이터를 약속된 표기법으로 표현 +- 업무의 흐름을 가시화, 명세화하여 정보시스템을 구축하기 위한 분석, 설계 과정의 일환 +- 업무 프로세스와 데이터를 분석하여 추상화 +- 데이터베이스 구축의 사전작업 및 업무 형상화 + +### 모델링 특징 - **추단명** + +- 추상화 + - 대상의 주요 특징을 추출하여 일정한 형식으로 표현 +- 단순화 + - 복잡한 현실대상을 단순하게 표현 + - UML, ERD같은 약속된 표기법 사용 +- 명확화 + - 관점에 따라 다르게 해석되지 않고 모호함이 없어야함 +- 모델링시 유의사항 + - 중복최소화 : DB 여러곳에 같은 정보를 중복하여 저장하지 않아야함 + - 비유연성 최소화 : 데이터의 정의와 테이터의 사용 프로세스를 분리하여 데이터, 프로세스의 변화가 프로그램과 DB에 미치는 영향 최소화 해야함 + - 비일관성 최소화 : 데이터 간의 상호 연관관계를 명확하게 정의하여 데이터를 일관성있게 유지해야함 + +### 모델링 3가지 관점 - **데프상** + +- 데이터 관점 (What) + - 데이터에 집중, 데이터들의 관계를 맺고 사용되는지를 모델링 + - 정적분석, 구조분석 +- 프로세스 관점 (How) + - 흐름에 집중, 일이 실제로 처리되는지를 모델링 + - 동적분석, 도메인분석 +- 데이터와 프로세스의 상관 관점 (Interaction) + - 데이터와 흐름간의 관계를 맺고 영향을 주고받는지를 모델링 + - CRUD분석 + +### 모델링 3가지 단계 - **개논물** + +- 개념적 데이터 모델링 + - 가장 높은 추상화 레벨, 포괄적 개념 + - 전사적 차원의 데이터 모델링 + - EA 수립 -> Entity, Attribute 도출 +- 논리적 데이터 모델링 + - 데이터 모델에 대한 Key, Attribute, Relationship 표현 + - 서로다른 DBMS에 적용이 가능한 수준의 추상화 레벨, 재사용성 높음 + - 정규화를 통한 중복 데이터 최소화 -> 식별자 도출, 관계 정의 +- 물리적 데이터 모델링 + - 특정 DBMS에 맞추어 구현이 가능한 수준의 모델링 + - DBMS의 성능, 보안, 가용성 고려하여 설계, 가장 낮은 추상화레벨 + - 성능향상을 위한 반정규화 수행 및 테이블, 인덱스, 함수 등을 생성 + +### 3단계 스키마 구조 - **외개내** + +> ANSI-SPARC정의, 데이터 독립성 보장을 위한 설계방법 + +- 외부 스키마 + - 사용자&애플리케이션 관점, DB스키마 정의 + - 다중 사용자 뷰 제공 +- 개념 스키마 + - 설계자 관점, 모든 사용자가 바라보는 데이터베이스 스키마를 통합하여 나타냄 + - 통합된 뷰 제공 +- 내부 스키마 + - 개발자 관점, 디스크나 메모리상의 물리적,실질적 저장구조 나타냄 + - 물리적 뷰 제공 + +### ERD + +- 데이터 모델링에대한 문서화 방법을 제공 +- 중요한 엔터티는 왼쪽 상단에 배치 +- 1976년 피터첸에 의해 Entity-Relationship Model 표기법 만들어짐 +- 작성순서 + 1. 엔터티 도출 + 2. 엔터티 배치 + 3. 엔터티 간 관계설정 4.관계명, 참여도, 필수/선택 여부 기술 + +## 1.2 엔터티 + +### 엔터티 개념 + +- DB의 구성요소중 독립적으로 식별 가능한 객체(Object) +- 도서관 DB 모델링시 엔터티 -> 회원, 대출, 도서 +- 보다 상세히 자신을 표현하기위해 속성(Attribute)라는 하위요소를 가진다. 회원 엔터티의 속성 -> 회원명, 주소, 전화번호 + +### 엔터티 특징 + +- 업무에서 필요하고 관리하고자 하는 정보 +- 유일한 식별자를 가져야 함 +- 영속적으로 존재하는 인스턴스가 두 개 이상인 집합을 이루어야함 +- 하위요소로 반드시 속성을 가져야함 +- 엔터티는 다른 엔터티와 한 개 이상의 관계를 가져야 함, 단 통계성 & 코드성 엔터티의 경우 관계 생략가능 + +### 엔터티 분류 + +- 발생 시점 / 상속 관계에 따른 분류 + - 기본 엔터티 : 고유한 주식별자를 가지는 독립적 엔터티, ex) 사원, 부서, 고객, 상품, 자재 + - 중심 엔터티 : 기본 엔터티로부터 주식별자를 상속받아 생성되며 업무의 중심역할을 하는 엔터티, ex) 급여, 주문 + - 행위 엔터티 : 두개 이상의 엔터티를 상속받아 생성되는 엔터티이며 내용이 자주변경되거나 데이터양 계속증가, ex) 주문내역, 급여내역 +- 물리적 형태의 존재 여부에 따른 분류 + - 유형 엔터티 : 물리적 형태가 존재하는 엔터티, ex) 사원, 상품, 학생 + - 개념 엔터티 : 개념적 정의되는 엔터티, ex) 부서, 상품분류, 강의 + - 사건 엔터티 : 업무를 수행하면서 발생하는 행위나 이벤트를 나타내는 엔터티, ex) 주문, 대여, 수강 + +### 교차 엔터티 + +- M:N 관계를 해소하기 위해 만들어진 엔터티 + +### 엔터티 명명법 + +- 엔터티 생성 의미대로 이름을 부여 +- 약어 사용하지 않는다, 너무길어질때만 약어를 표준화하여 사용 +- 대문자를 사용하며 단수명사를 사용 +- 유일성, 중복제거 + +## 1.3 속성 + +### 속성 개념 + +- 엔터티에 대한 자세하고 구체적인 정보, 엔티의 하위요소 +- 업무 프로세스에 꼭 필요한 것들로 최소화 +- 의미상으로 더 이상 분리되지 않는 최소의 데이터 단위 + +### 속성 값 + +- 속성이 가질 수 있는 특정 값 +- 속성값이 으미적으로 다중 값을 포함할때, 1차 정규화 진행 +- + +### 엔터티, 인스턴스, 속성값 특징 + +- 한 개의 엔터티는 두 개 이상의 인스턴스를 가짐, 엔터티는 인스턴스의 집합 +- 한 개의 엔터티는 두 개 이상의 속성을 가짐, 엔터티는 속성의 집합 +- 한 개의 속성은 한 개의 속성값만 가짐 + +### 속성의 분류 + +- 속성의 특성에 따른 분류 + - 기본 속성 : 엔터티가 본래 가지고 있어야 하는 속성 + - 설계 속성 : 설계 시 필요하다고 판단되어 도출된 속성 + - 파생 속성 : 다른 속성으로부터 계산되거나 규칙에 따라 변형되어 만들어진 속성 +- 속성의 구성방식에 따른 분류 + - PK(기본키) 속성 : 인스턴스를 유일하게 식별할 수 있는 속성 + - FK(외래키) 속성 : 관계를 통해 다른 엔터티의 속성을 가져와 포함시킨 속성 + - 일반 속성 : PK,FK제외 나머지 + +### 도메인 + +- 속성이 가질 수 있는 값의 범위(데이터 타입, 크기)를 정의한 것 + +## 1.4 관계 + +### 관계의 개념 + +> 엔터티 간 맺고 있는 연관성 + +- 존재적 관계 + - 소속관계를 갖는 존재 자체로 서로 연관성을 갖는 관계, ex) 사원과 부서의 관계 +- 행위적 관계 + - 엔터티가 특정 행위나 이벤트를 일으킬 경우에 발생하는 관계, ex) 고객과 주문의 관계 + +## 1.5 식별자 + +### 식별자의 개념 + +- 인스턴스를 유일하게 구별할 수 있는 속성 + +### 주식별자 + +> 엔터티 인스턴스를 유일하게 구별해주는 식별자, PK를 말함 + +- 유일성 : 각 엔터티 인스턴스를 유일하게 구별 +- 최소성 : 최소성을 보장하면서 최소 개수의 속성 +- 붋변성 : 속성값이 최초 생성시 부여된 값에서 변하면안됨 +- 존재성 : 반드시 값을 가져야함, NOT NULL + +### 식별자의 분류 + +- 대표성 여부에 따른 분류 + - 주식별자(PK) : 인스턴스를 유일하게 구별하는 식별자, 유일성, 최소성, 불변성, 존재성 만족 + - 보조식별자(AK) : 유일하게 구별할 수 있는 식별자, 대표성을 가지지못해 다른엔터티와 참조관계 연결이 불가한 식별자 + - PK와AK모두 후보키에 속함, 유일성, 최소성 만족 +- 스스로 생성 여부에 따른 분류 + - 내부식별자 : 엔터티 내부에서 스스로 만들어지는 식별자 + - 외부식별자(FK) : 관계를 통해 다른 엔터티로부터 받아오는 식별자 +- 속성의 수에 따른 분류 + - 단일식별자 : 식별자를 구성하는 속성이 하나인 식별자 + - 복합식별자 : 식별자를 구성하는 속성이 둘 이상이 식별자 +- 대체 여부에 따른 분류 + - 본질 식별자 : 업무에 존재하는 본래 식별자, 원조식별자라고도 함 + - 인조식별자 : 업무에 존재하지않으나 원조식별자가 복잡하여 인위적으로만든 식별자, 대리식별자라고도 함 + +### 식별자 관계, 비식별자 관계 + +- 식별자 관계 + - ERD작성시 실선표현 + - 강한 연결관계 표현, 부모소멸시 자식도같이 소멸하는경우 사용 +- 비식별자 관계 + - ERD작성시 점선 표현 + - 약한 연결관계 표현, 부모 자식 엔터티가 다른 생명주기를 가졌을때 사용