Skip to content

Commit dbf65e8

Browse files
authored
Merge pull request #1392 from clara-shin/main
[clara-shin] WEEK 05 solutions
2 parents cf65e7b + aaeb0b1 commit dbf65e8

File tree

6 files changed

+278
-0
lines changed

6 files changed

+278
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* μ‹œκ°„ λ³΅μž‘λ„ O(n)
3+
* 곡간 λ³΅μž‘λ„ O(1)
4+
*
5+
* 그리디 μ•Œκ³ λ¦¬μ¦˜
6+
* ν˜„μž¬κΉŒμ§€μ˜ μ΅œμ € 가격을 κΈ°μ–΅ν•˜κ³ , κ·Έ 가격에 샀을 λ•Œμ˜ 이읡을 계속 κ³„μ‚°ν•˜μ—¬ μ΅œλŒ€ 이읡을 ꡬ함
7+
*/
8+
9+
/**
10+
* @param {number[]} prices
11+
* @return {number}
12+
*/
13+
var maxProfit = function (prices) {
14+
let minPrice = prices[0]; // μ΅œμ € 가격 μ΄ˆκΈ°ν™” (첫 λ‚  가격)
15+
let maxProfit = 0; // μ΅œλŒ€ 이읡 μ΄ˆκΈ°ν™” (아직 이읡 μ—†μŒ)
16+
17+
// 두 번째 λ‚ λΆ€ν„°
18+
for (let i = 1; i < prices.length; i++) {
19+
minPrice = Math.min(minPrice, prices[i]); // μ΅œμ € 가격 κ°±μ‹ 
20+
maxProfit = Math.max(maxProfit, prices[i] - minPrice); // μ΅œλŒ€ 이읡 κ°±μ‹ 
21+
}
22+
23+
return maxProfit;
24+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* λ¬Έμžμ—΄ 리슀트λ₯Ό ν•˜λ‚˜μ˜ λ¬Έμžμ—΄λ‘œ μΈμ½”λ”©ν•˜κ³ , λ‹€μ‹œ λ””μ½”λ”© ν•˜κΈ°
3+
*
4+
* μ ‘κ·Ό 방법:
5+
* 길이 기반 인코딩 => 각 λ¬Έμžμ—΄λ§ˆλ‹€ "길이#λ¬Έμžμ—΄" ν˜•μ‹μœΌλ‘œ 인코딩
6+
* "#"을 κΈ°μ€€μœΌλ‘œ λ¬Έμžμ—΄μ„ λ‚˜λˆ„κ³ , 길이λ₯Ό μ΄μš©ν•΄ μ›λž˜ λ¬Έμžμ—΄μ„ λ³΅μ›ν•˜μ—¬ λ””μ½”λ”©
7+
*/
8+
9+
/**
10+
* @param {string[]} strs - 인코딩할 λ¬Έμžμ—΄ 리슀트
11+
* @return {string} - μΈμ½”λ”©λœ λ¬Έμžμ—΄
12+
*/
13+
var encode = function (strs) {
14+
if (!strs || strs.length === 0) return '';
15+
return strs.map((str) => str.length + '#' + str).join('');
16+
};
17+
18+
/**
19+
* @param {string} s - λ””μ½”λ”©ν•  μΈμ½”λ”©λœ λ¬Έμžμ—΄
20+
* @return {string[]} - μ›λž˜μ˜ λ¬Έμžμ—΄ 리슀트
21+
*/
22+
var decode = function (s) {
23+
if (!s || s.length === 0) return [];
24+
25+
const result = [];
26+
let i = 0;
27+
28+
while (i < s.length) {
29+
const delimiterIndex = s.indexOf('#', i); // '#'의 μœ„μΉ˜ μ°ΎκΈ°
30+
const length = parseInt(s.slice(i, delimiterIndex)); // 길이 μΆ”μΆœ
31+
32+
const start = delimiterIndex + 1; // λ¬Έμžμ—΄ μ‹œμž‘ μœ„μΉ˜
33+
result.push(s.slice(start, start + length)); // μ•Œμ•„λ‚Έ 길이만큼 λ¬Έμžμ—΄ μΆ”μΆœ ν›„ 결과에 μΆ”κ°€
34+
i = start + length; // λ‹€μŒ λ¬Έμžμ—΄ μ‹œμž‘ μœ„μΉ˜λ‘œ 포인터 이동
35+
}
36+
37+
return result;
38+
};

β€Žgroup-anagrams/clara-shin.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* λ¬Έμžμ—΄ λ°°μ—΄ strsκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, μ• λ„ˆκ·Έλž¨λΌλ¦¬ κ·Έλ£Ήν™”ν•˜λŠ” 문제
3+
* μ• λ„ˆκ·Έλž¨: 같은 문자λ₯Ό μž¬λ°°μ—΄ν•˜μ—¬ λ§Œλ“€ 수 μžˆλŠ” 단어듀
4+
*
5+
* μ ‘κ·Ό 방법: 각 문자 μΆœν˜„λΉˆλ„λ₯Ό μΉ΄μš΄νŒ…ν•˜λŠ” 방식
6+
* 1. 각 λ¬Έμžμ—΄μ„ μ•ŒνŒŒλ²³ 개수둜 λ³€ν™˜ν•˜μ—¬ ν‚€λ₯Ό 생성
7+
* 2. Map을 μ‚¬μš©ν•˜μ—¬ ν‚€λ₯Ό κΈ°μ€€μœΌλ‘œ λ¬Έμžμ—΄μ„ κ·Έλ£Ήν™”
8+
* 3. Map의 값듀을 λ°°μ—΄λ‘œ λ³€ν™˜ν•˜μ—¬ λ°˜ν™˜
9+
*
10+
* μ‹œκ°„λ³΅μž‘λ„: O(n * k) (n: λ¬Έμžμ—΄ 개수, k: λ¬Έμžμ—΄ 길이) -> λ‹¨μˆœ μΉ΄μš΄νŒ…
11+
* κ³΅κ°„λ³΅μž‘λ„: O(n * k) -> λͺ¨λ“  λ¬Έμžμ—΄μ„ μ €μž₯ν•΄μ•Ό ν•˜λ―€λ‘œ
12+
*/
13+
14+
/**
15+
* @param {string[]} strs
16+
* @return {string[][]}
17+
*/
18+
var groupAnagrams = function (strs) {
19+
const map = new Map();
20+
21+
for (let str of strs) {
22+
const count = new Array(26).fill(0); // μ•ŒνŒŒλ²³ 개수 μ΄ˆκΈ°ν™”
23+
for (let i = 0; i < str.length; i++) {
24+
const index = str.charCodeAt(i) - 'a'.charCodeAt(0); // μ•ŒνŒŒλ²³ 인덱슀 계산
25+
count[index]++; // ν•΄λ‹Ή μ•ŒνŒŒλ²³ 개수 증가
26+
}
27+
const key = count.join('#'); // μ•ŒνŒŒλ²³ 개수λ₯Ό λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜μ—¬ ν‚€ 생성
28+
if (!map.has(key)) {
29+
map.set(key, []); // ν‚€κ°€ μ—†μœΌλ©΄ μƒˆλ‘œμš΄ λ°°μ—΄ 생성
30+
}
31+
map.get(key).push(str); // ν•΄λ‹Ή 킀에 λ¬Έμžμ—΄ μΆ”κ°€
32+
}
33+
34+
return Array.from(map.values()); // Map의 값듀을 λ°°μ—΄λ‘œ λ³€ν™˜ν•˜μ—¬ λ°˜ν™˜
35+
};
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// TrieNode 클래슀 μ •μ˜: 트라이의 각 λ…Έλ“œλ₯Ό ν‘œν˜„
2+
var TrieNode = function () {
3+
this.children = new Map(); // μžμ‹ λ…Έλ“œλ₯Ό Map으둜 μ €μž₯
4+
this.isEnd = false; // λ‹¨μ–΄μ˜ 끝을 ν‘œμ‹œν•˜λŠ” ν”Œλž˜κ·Έ
5+
};
6+
7+
// Trie 클래슀 μ •μ˜: 트라이 자료ꡬ쑰λ₯Ό ν‘œν˜„
8+
var Trie = function () {
9+
this.root = new TrieNode(); // 루트 λ…Έλ“œ
10+
};
11+
12+
/**
13+
* @param {string} word
14+
* @return {void}
15+
*/
16+
Trie.prototype.insert = function (word) {
17+
let node = this.root; // ν˜„μž¬ λ…Έλ“œλ₯Ό 루트둜 μ΄ˆκΈ°ν™”
18+
19+
for (let i = 0; i < word.length; i++) {
20+
const char = word[i]; // ν˜„μž¬ 문자
21+
22+
// ν˜„μž¬ λ¬Έμžμ— λŒ€ν•œ μžμ‹ λ…Έλ“œκ°€ μ—†μœΌλ©΄ μƒˆλ‘œ 생성
23+
if (!node.children.has(char)) {
24+
node.children.set(char, new TrieNode());
25+
}
26+
27+
// λ‹€μŒ μžμ‹ λ…Έλ“œλ‘œ 이동
28+
node = node.children.get(char);
29+
}
30+
node.isEnd = true; // λ‹¨μ–΄μ˜ 끝을 ν‘œμ‹œ
31+
};
32+
33+
/**
34+
* @param {string} word
35+
* @return {boolean}
36+
*/
37+
Trie.prototype.search = function (word) {
38+
const node = this._searchPrefix(word); // μ£Όμ–΄μ§„ λ‹¨μ–΄μ˜ λ…Έλ“œλ₯Ό 찾음
39+
return node !== null && node.isEnd === true; // κ²½λ‘œκ°€ μ‘΄μž¬ν•˜κ³ , λ§ˆμ§€λ§‰ λ…Έλ“œκ°€ λ‹¨μ–΄μ˜ 끝인지 확인
40+
};
41+
42+
/**
43+
* @param {string} prefix
44+
* @return {boolean}
45+
*/
46+
Trie.prototype.startsWith = function (prefix) {
47+
return this._searchPrefix(prefix) !== null; // κ²½λ‘œκ°€ μ‘΄μž¬ν•˜λŠ”μ§€λ§Œ 확인
48+
};
49+
50+
/**
51+
* 헬퍼 λ©”μ„œλ“œ: μ£Όμ–΄μ§„ 접두사에 λŒ€ν•œ 경둜λ₯Ό μ°ΎλŠ” λ©”μ„œλ“œ
52+
* @param {string} str
53+
* @return {TrieNode|null} 경둜의 λ§ˆμ§€λ§‰ λ…Έλ“œ λ˜λŠ” null
54+
* @private
55+
*/
56+
Trie.prototype._searchPrefix = function (str) {
57+
let node = this.root; // ν˜„μž¬ λ…Έλ“œλ₯Ό 루트둜 μ΄ˆκΈ°ν™”
58+
59+
// μ£Όμ–΄μ§„ λ¬Έμžμ—΄μ˜ 각 λ¬Έμžμ— λŒ€ν•΄ λ…Έλ“œ 탐색
60+
for (let i = 0; i < str.length; i++) {
61+
const char = str[i]; // ν˜„μž¬ 문자
62+
63+
// ν˜„μž¬ λ¬Έμžμ— λŒ€ν•œ μžμ‹ λ…Έλ“œκ°€ μ—†μœΌλ©΄ null 리턴
64+
if (!node.children.has(char)) {
65+
return null;
66+
}
67+
68+
// λ‹€μŒ μžμ‹ λ…Έλ“œλ‘œ 이동
69+
node = node.children.get(char);
70+
}
71+
return node; // 경둜의 λ§ˆμ§€λ§‰ λ…Έλ“œ λ°˜ν™˜
72+
};
73+
/**
74+
* Your Trie object will be instantiated and called as such:
75+
* var obj = new Trie()
76+
* obj.insert(word)
77+
* var param_2 = obj.search(word)
78+
* var param_3 = obj.startsWith(prefix)
79+
*/

β€Žword-break/clara-shin.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* λ¬Έμžμ—΄ sκ°€ μ£Όμ–΄μ§„ 단어 사전 wordDict의 λ‹¨μ–΄λ“€λ‘œ 뢄리될 수 μžˆλŠ”μ§€ ν™•μΈν•˜λŠ” 문제
3+
* λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ°(DP)
4+
* μ‹œκ°„ λ³΅μž‘λ„: O(n * k) (k: μ΅œλŒ€ 단어 길이)
5+
* 곡간 λ³΅μž‘λ„: O(n) (DP λ°°μ—΄ + 단어 μ§‘ν•©)
6+
*/
7+
8+
/**
9+
* @param {string} s
10+
* @param {string[]} wordDict
11+
* @return {boolean}
12+
*/
13+
var wordBreak = function (s, wordDict) {
14+
const n = s.length;
15+
const dp = new Array(n + 1).fill(false); // DP λ°°μ—΄ μ΄ˆκΈ°ν™”
16+
dp[0] = true; // 빈 λ¬Έμžμ—΄μ€ 항상 뢄리 κ°€λŠ₯
17+
18+
const wordSet = new Set(wordDict); // 단어 사전을 Set으둜 λ³€ν™˜: κ²€μƒ‰μ‹œκ°„ O(1)
19+
20+
const maxWordLength = Math.max(...wordDict.map((word) => word.length)); // λ‹¨μ–΄μ˜ μ΅œλŒ€ 길이 μ°ΎκΈ°
21+
22+
for (let i = 0; i <= n; i++) {
23+
// κ°€λŠ₯ν•œ 단어 길이만 검사
24+
for (let j = Math.max(0, i - maxWordLength); j < i; j++) {
25+
if (dp[j] && wordSet.has(s.substring(j, i))) {
26+
// dp[j]κ°€ true이고, jλΆ€ν„° iκΉŒμ§€μ˜ λΆ€λΆ„ λ¬Έμžμ—΄μ΄ 단어 사전에 μ‘΄μž¬ν•˜λŠ” 경우
27+
dp[i] = true;
28+
break;
29+
}
30+
}
31+
}
32+
33+
return dp[n];
34+
};

β€Žword-search/clara-shin.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* μ£Όμ–΄μ§„ 격자(board)μ—μ„œ νŠΉμ • 단어(word)κ°€ μ‘΄μž¬ν•˜λŠ”μ§€ ν™•μΈν•˜λŠ” ν•¨μˆ˜
3+
*
4+
* μ ‘κ·Ό 방식:DFS(깊이 μš°μ„  탐색) + λ°±νŠΈλž˜ν‚Ή
5+
* μ‹œκ°„ λ³΅μž‘λ„: O(m * n * 4^k) (m: ν–‰, n: μ—΄, k: 단어 길이)
6+
* 곡간 λ³΅μž‘λ„: O(m * n) (μ΅œλŒ€ 깊이 m*n)
7+
*
8+
*/
9+
10+
/**
11+
* @param {character[][]} board
12+
* @param {string} word
13+
* @return {boolean}
14+
*/
15+
var exist = function (board, word) {
16+
const m = board.length;
17+
const n = board[0].length;
18+
19+
const directions = [
20+
[-1, 0],
21+
[1, 0],
22+
[0, -1],
23+
[0, 1],
24+
];
25+
26+
function dfs(row, col, index) {
27+
if (index === word.length) {
28+
return true;
29+
}
30+
31+
if (row < 0 || row >= m || col < 0 || col >= n || board[row][col] !== word[index]) {
32+
return false;
33+
}
34+
35+
// ν˜„μž¬ μ…€ λ°©λ¬Έ ν‘œμ‹œ (μž„μ‹œλ‘œ λ³€κ²½)
36+
const temp = board[row][col];
37+
board[row][col] = '#'; // λ°©λ¬Έν•œ 셀을 특수 문자둜 ν‘œμ‹œ
38+
39+
// λ„€ λ°©ν–₯ 탐색
40+
for (const [dx, dy] of directions) {
41+
const newRow = row + dx;
42+
const newCol = col + dy;
43+
44+
if (dfs(newRow, newCol, index + 1)) {
45+
// 단어λ₯Ό μ°Ύμ•˜μœΌλ©΄ μ›λž˜ κ°’ λ‘€λ°± ν›„ true λ°˜ν™˜
46+
board[row][col] = temp;
47+
return true;
48+
}
49+
}
50+
51+
// λ°±νŠΈλž˜ν‚Ή(ν˜„μž¬ μ…€μ˜ μ›λž˜ κ°’ λ‘€λ°±)
52+
board[row][col] = temp;
53+
54+
return false;
55+
}
56+
57+
// 격자의 λͺ¨λ“  μ…€μ—μ„œ μ‹œμž‘μ μœΌλ‘œ μ‹œλ„
58+
for (let i = 0; i < m; i++) {
59+
for (let j = 0; j < n; j++) {
60+
if (board[i][j] === word[0] && dfs(i, j, 0)) {
61+
return true;
62+
}
63+
}
64+
}
65+
66+
// λͺ¨λ“  μ‹œμž‘μ μ—μ„œ μ‹€νŒ¨ν•˜λ©΄
67+
return false;
68+
};

0 commit comments

Comments
Β (0)