diff --git a/longest-repeating-character-replacement/krokerdile.js b/longest-repeating-character-replacement/krokerdile.js new file mode 100644 index 000000000..185ffa22a --- /dev/null +++ b/longest-repeating-character-replacement/krokerdile.js @@ -0,0 +1,28 @@ +/** + * @param {string} s + * @param {number} k + * @return {number} + */ +var characterReplacement = function(s, k) { + let left = 0; + let maxCount = 0; + const freq = new Array(26).fill(0); // 알파벳 빈도수 저장 + + let result = 0; + + for (let right = 0; right < s.length; right++) { + const idx = s.charCodeAt(right) - 65; // A ~ Z -> 0 ~ 25 + freq[idx]++; + maxCount = Math.max(maxCount, freq[idx]); + + // 현재 윈도우 크기 - 가장 많은 문자 수 > k 면 왼쪽 포인터 이동 + while ((right - left + 1) - maxCount > k) { + freq[s.charCodeAt(left) - 65]--; + left++; + } + + result = Math.max(result, right - left + 1); + } + + return result; +}; diff --git a/minimum-window-substring/krokerdile.js b/minimum-window-substring/krokerdile.js new file mode 100644 index 000000000..89a0f51fb --- /dev/null +++ b/minimum-window-substring/krokerdile.js @@ -0,0 +1,52 @@ +/** + * @param {string} s + * @param {string} t + * @return {string} + */ +var minWindow = function(s, t) { + if (s.length < t.length) return ""; + + // 1. t의 문자 개수를 세기 + const targetMap = new Map(); + for (let char of t) { + targetMap.set(char, (targetMap.get(char) || 0) + 1); + } + + let left = 0; + let right = 0; + let minLen = Infinity; + let minStart = 0; + + let required = targetMap.size; // 만족시켜야 할 문자 종류 수 + let formed = 0; + const windowMap = new Map(); + + while (right < s.length) { + const char = s[right]; + windowMap.set(char, (windowMap.get(char) || 0) + 1); + + // 문자 개수가 딱 맞는 경우 + if (targetMap.has(char) && windowMap.get(char) === targetMap.get(char)) { + formed++; + } + + // 모든 문자가 충족될 경우 -> 왼쪽 포인터 당겨보기 + while (left <= right && formed === required) { + if (right - left + 1 < minLen) { + minLen = right - left + 1; + minStart = left; + } + + const leftChar = s[left]; + windowMap.set(leftChar, windowMap.get(leftChar) - 1); + if (targetMap.has(leftChar) && windowMap.get(leftChar) < targetMap.get(leftChar)) { + formed--; + } + left++; + } + + right++; + } + + return minLen === Infinity ? "" : s.slice(minStart, minStart + minLen); +}; diff --git a/pacific-atlantic-water-flow/krokerdile.js b/pacific-atlantic-water-flow/krokerdile.js new file mode 100644 index 000000000..7cec031bb --- /dev/null +++ b/pacific-atlantic-water-flow/krokerdile.js @@ -0,0 +1,44 @@ +/** + * @param {number[][]} heights + * @return {number[][]} + */ +const pacificAtlantic = (heights) => { + const m = heights.length; + const n = heights[0].length; + const pacific = Array.from({ length: m }, () => Array(n).fill(false)); + const atlantic = Array.from({ length: m }, () => Array(n).fill(false)); + + const dfs = (r, c, visited, prevHeight) => { + if ( + r < 0 || c < 0 || r >= m || c >= n || + visited[r][c] || heights[r][c] < prevHeight + ) return; + + visited[r][c] = true; + + dfs(r + 1, c, visited, heights[r][c]); + dfs(r - 1, c, visited, heights[r][c]); + dfs(r, c + 1, visited, heights[r][c]); + dfs(r, c - 1, visited, heights[r][c]); + }; + + for (let i = 0; i < m; i++) { + dfs(i, 0, pacific, heights[i][0]); + dfs(i, n - 1, atlantic, heights[i][n - 1]); + } + + for (let j = 0; j < n; j++) { + dfs(0, j, pacific, heights[0][j]); + dfs(m - 1, j, atlantic, heights[m - 1][j]); + } + + const result = []; + for (let i = 0; i < m; i++) { + for (let j = 0; j < n; j++) { + if (pacific[i][j] && atlantic[i][j]) { + result.push([i, j]); + } + } + } + return result; +};