diff --git a/best-time-to-buy-and-sell-stock/clara-shin.js b/best-time-to-buy-and-sell-stock/clara-shin.js new file mode 100644 index 000000000..6ca8c13af --- /dev/null +++ b/best-time-to-buy-and-sell-stock/clara-shin.js @@ -0,0 +1,24 @@ +/** + * 시간 복잡도 O(n) + * 공간 복잡도 O(1) + * + * 그리디 알고리즘 + * 현재까지의 최저 가격을 기억하고, 그 가격에 샀을 때의 이익을 계속 계산하여 최대 이익을 구함 + */ + +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function (prices) { + let minPrice = prices[0]; // 최저 가격 초기화 (첫 날 가격) + let maxProfit = 0; // 최대 이익 초기화 (아직 이익 없음) + + // 두 번째 날부터 + for (let i = 1; i < prices.length; i++) { + minPrice = Math.min(minPrice, prices[i]); // 최저 가격 갱신 + maxProfit = Math.max(maxProfit, prices[i] - minPrice); // 최대 이익 갱신 + } + + return maxProfit; +}; diff --git a/group-anagrams/clara-shin.js b/group-anagrams/clara-shin.js new file mode 100644 index 000000000..d6c1baad5 --- /dev/null +++ b/group-anagrams/clara-shin.js @@ -0,0 +1,35 @@ +/** + * 문자열 배열 strs가 주어졌을 때, 애너그램끼리 그룹화하는 문제 + * 애너그램: 같은 문자를 재배열하여 만들 수 있는 단어들 + * + * 접근 방법: 각 문자 출현빈도를 카운팅하는 방식 + * 1. 각 문자열을 알파벳 개수로 변환하여 키를 생성 + * 2. Map을 사용하여 키를 기준으로 문자열을 그룹화 + * 3. Map의 값들을 배열로 변환하여 반환 + * + * 시간복잡도: O(n * k) (n: 문자열 개수, k: 문자열 길이) -> 단순 카운팅 + * 공간복잡도: O(n * k) -> 모든 문자열을 저장해야 하므로 + */ + +/** + * @param {string[]} strs + * @return {string[][]} + */ +var groupAnagrams = function (strs) { + const map = new Map(); + + for (let str of strs) { + const count = new Array(26).fill(0); // 알파벳 개수 초기화 + for (let i = 0; i < str.length; i++) { + const index = str.charCodeAt(i) - 'a'.charCodeAt(0); // 알파벳 인덱스 계산 + count[index]++; // 해당 알파벳 개수 증가 + } + const key = count.join('#'); // 알파벳 개수를 문자열로 변환하여 키 생성 + if (!map.has(key)) { + map.set(key, []); // 키가 없으면 새로운 배열 생성 + } + map.get(key).push(str); // 해당 키에 문자열 추가 + } + + return Array.from(map.values()); // Map의 값들을 배열로 변환하여 반환 +}; diff --git a/word-search/clara-shin.js b/word-search/clara-shin.js new file mode 100644 index 000000000..2e13920f4 --- /dev/null +++ b/word-search/clara-shin.js @@ -0,0 +1,68 @@ +/** + * 주어진 격자(board)에서 특정 단어(word)가 존재하는지 확인하는 함수 + * + * 접근 방식:DFS(깊이 우선 탐색) + 백트래킹 + * 시간 복잡도: O(m * n * 4^k) (m: 행, n: 열, k: 단어 길이) + * 공간 복잡도: O(m * n) (최대 깊이 m*n) + * + */ + +/** + * @param {character[][]} board + * @param {string} word + * @return {boolean} + */ +var exist = function (board, word) { + const m = board.length; + const n = board[0].length; + + const directions = [ + [-1, 0], + [1, 0], + [0, -1], + [0, 1], + ]; + + function dfs(row, col, index) { + if (index === word.length) { + return true; + } + + if (row < 0 || row >= m || col < 0 || col >= n || board[row][col] !== word[index]) { + return false; + } + + // 현재 셀 방문 표시 (임시로 변경) + const temp = board[row][col]; + board[row][col] = '#'; // 방문한 셀을 특수 문자로 표시 + + // 네 방향 탐색 + for (const [dx, dy] of directions) { + const newRow = row + dx; + const newCol = col + dy; + + if (dfs(newRow, newCol, index + 1)) { + // 단어를 찾았으면 원래 값 롤백 후 true 반환 + board[row][col] = temp; + return true; + } + } + + // 백트래킹(현재 셀의 원래 값 롤백) + board[row][col] = temp; + + return false; + } + + // 격자의 모든 셀에서 시작점으로 시도 + for (let i = 0; i < m; i++) { + for (let j = 0; j < n; j++) { + if (board[i][j] === word[0] && dfs(i, j, 0)) { + return true; + } + } + } + + // 모든 시작점에서 실패하면 + return false; +};