diff --git a/container-with-most-water/Yjason-K.ts b/container-with-most-water/Yjason-K.ts new file mode 100644 index 000000000..3f528615e --- /dev/null +++ b/container-with-most-water/Yjason-K.ts @@ -0,0 +1,34 @@ +/** + * 계산할 수 있는 면적에서 가장 큰 면적 구하기. + * + * @param {number[]} height - x 축 방향의 높이 배열 + * @returns {number} - 가장 넓은 면적 반환 + * + * 시간 복잡도 O(n) + * - n은 height 배열의 길이 + * + * 공간 복잡도 O(1) + * - 포인터 및 결과값 저장 공간만 사용 + */ +function maxArea(height: number[]): number { + let start = 0; // 시작 포인터 초기화 + let end = height.length - 1; // 끝 포인터 초기화 + let result = 0; // 최대 면적 저장 + + while (start < end) { + // 현재 면적 계산 + const currentArea = Math.min(height[start], height[end]) * (end - start); + // 최대 면적 업데이트 + result = Math.max(result, currentArea); + + // 포인터 이동 (높이가 낮은 쪽을 이동) + if (height[start] > height[end]) { + end--; + } else { + start++; + } + } + + return result; +} + diff --git a/longest-increasing-subsequence/Yjason-K.ts b/longest-increasing-subsequence/Yjason-K.ts new file mode 100644 index 000000000..75817a07f --- /dev/null +++ b/longest-increasing-subsequence/Yjason-K.ts @@ -0,0 +1,41 @@ + +/** + * 최장 증가 부분 수열을 계산 + * @param {number[]} nums + * @returns {number} - 조건을 만족하는 수열의 최대 길이 + * + * 시간 복잡도: O( n log(n) ) + * - n은 배열의 길이 + * - 각 요소를 처리할 때 이분 탐색으로 위치를 찾기 때문에 log(n)이 소요됨 + * 공간 복잡도: O(n) + * - 배열에 최대 n개의 요소를 저장 가능 + */ +function lengthOfLIS(nums: number[]): number { + // 수열을 저장할 배열 + const sequences: number[] = []; + + for (let num of nums) { + // 이분 탐색을 사용하여 num이 들어갈 위치름 찾음 + let left = 0; + let right = sequences.length; + + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (sequences[mid] < num) { + left = mid + 1; + } else { + right = mid; + } + } + + // 새로운 요소를 추가하거나 기존 요소를 대체 + if (left < sequences.length) { + sequences[left] = num; + } else { + sequences.push(num) + } + } + + return sequences.length; +} + diff --git a/spiral-matrix/Yjason-K.ts b/spiral-matrix/Yjason-K.ts new file mode 100644 index 000000000..c5a41e05a --- /dev/null +++ b/spiral-matrix/Yjason-K.ts @@ -0,0 +1,52 @@ +/** + * 2차원 배열을 [0][0] 시작으로 시계방향으로 1차원 배열로 변환. + * + * @param {number[][]} matrix - 2차원 배열 + * @returns {number[]} 시계 방향으로 1차원으로 펼친 배열 + * + * + * - 시간 복잡도: O(n * m) + * 모든 원소가 한 번씩 방문되므로 행과 열의 곱에 비례합니다. + * + * - 공간 복잡도: O(n * m) + * 방문 배열과 출력 목록이 필요하며, 둘 다 입력 배열의 크기와 같은 추가 메모리가 사용됩니다. + */ +function spiralOrder(matrix: number[][]): number[] { + // 방분 배열 생성 + const visited: boolean[][] = Array.from({length: matrix.length}, () => Array(matrix[0].length).fill(false)); + // flatten할 배열 + const orderList: number[] = []; + // 전체 길이 + const totalLength = matrix.length * matrix[0].length; + // 진행 방향 (우, 하, 좌, 상) + const directions = [[0,1], [1,0], [0,-1], [-1,0]]; + + let i = 0; // 시작 i 좌표 + let j = 0; // 시작 j 좌표 + let directionIndex = 0; // 우방향부터 시작 + + while (orderList.length < totalLength) { + // 현재 위치를 방문 처리 orderList에 추가 + orderList.push(matrix[i][j]) + visited[i][j] = true; + + // 다음 위치 + let nextI = i + directions[directionIndex][0]; + let nextJ = j + directions[directionIndex][1]; + + // 다음 위치가 범위 내이고 방문하지 않았다면 그 위치로 이동 + if (nextI >= 0 && nextI < matrix.length && nextJ >= 0 && nextJ < matrix[0].length && !visited[nextI][nextJ]) { + i = nextI; + j = nextJ; + } else { + // 다음 위치가 범위를 벗어나거나, 방문한 경우 방향 변경 + directionIndex = (directionIndex + 1) % 4; + i += directions[directionIndex][0]; + j += directions[directionIndex][1]; + } + + } + + return orderList; +} + diff --git a/valid-parentheses/Yjason-K.ts b/valid-parentheses/Yjason-K.ts new file mode 100644 index 000000000..b37ca2efa --- /dev/null +++ b/valid-parentheses/Yjason-K.ts @@ -0,0 +1,35 @@ +/** + * 주어진 문자열 s가 유효한 괄호 문자열인지 확인. + * @param {string} s - 입력 문자열 (괄호만 포함됨) + * @returns {boolean} - 유효한 괄호 문자열이면 true, 아니면 false + * + * 시간 복잡도: O(n) + * - 문자열의 길이 n만큼 한 번씩 순회하며, 각 문자에 대해 고정된 연산(스택 조작)을 수행. + * + * 공간 복잡도: O(n) + * - 최악의 경우 스택에 여는 괄호 n개를 저장해야 하므로 O(n)의 추가 메모리가 필요합니다. + */ +function isValid(s: string): boolean { + if (s.length % 2 !== 0) return false; + if (s === '') return true; + + const bracketSets: Record = { '(': ')', '{': '}', '[': ']' }; + const bracketStack: string[] = []; + + for (const char of s) { + if (char in bracketSets) { + // 여는 괄호인 경우 스택에 추가 + bracketStack.push(char); + } else { + // 닫는 괄호인 경우 스택에서 마지막 여는 괄호를 꺼냄 + const lastOpeningBracket = bracketStack.pop(); + // 유효하지 않은 괄호 조합인 경우 + if (bracketSets[lastOpeningBracket!] !== char) { + return false; + } + } + } + + // 스택이 비어있으면 모든 괄호가 유효 + return bracketStack.length === 0; +}