Skip to content

Commit

Permalink
Merge pull request #852 from lledellebell/main
Browse files Browse the repository at this point in the history
[dd_._._bb] Week 5
  • Loading branch information
lledellebell authored Jan 10, 2025
2 parents d378148 + acacff5 commit f244f24
Show file tree
Hide file tree
Showing 5 changed files with 356 additions and 0 deletions.
43 changes: 43 additions & 0 deletions best-time-to-buy-and-sell-stock/lledellebell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
*
* @problem
* ์ฃผ์–ด์ง„ ์ฃผ์‹ ๊ฐ€๊ฒฉ ๋ฐฐ์—ด์—์„œ ํ•œ ๋ฒˆ์˜ ๋งค์ˆ˜์™€ ํ•œ ๋ฒˆ์˜ ๋งค๋„๋ฅผ ํ†ตํ•ด ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์ด์ต์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
* ๋งค์ˆ˜๋Š” ๋งค๋„๋ณด๋‹ค ๋ฐ˜๋“œ์‹œ ๋จผ์ € ์ด๋ฃจ์–ด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
*
* @constraints
* - 1 <= prices.length <= 105
* - 0 <= prices[i] <= 104
*
* @param {number[]} prices - ๊ฐ ๋‚ ์งœ๋ณ„ ์ฃผ์‹ ๊ฐ€๊ฒฉ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฐ์—ด
* @returns {number} ์ตœ๋Œ€ ์ด์ต (์ด์ต์„ ๋‚ผ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ 0 ๋ฐ˜ํ™˜)
*
* @example
* maxProfit([7, 1, 5, 3, 6, 4]); // 5 (2์ผ์ฐจ์— ๋งค์ˆ˜ํ•˜๊ณ  5์ผ์ฐจ์— ๋งค๋„)
* maxProfit([7, 6, 4, 3, 1]); // 0 (์ด์ต์„ ๋‚ผ ์ˆ˜ ์—†์Œ)
*
* @complexity
* - ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n)
* ๋ฐฐ์—ด์„ ํ•œ ๋ฒˆ ์ˆœํšŒํ•˜๋ฉฐ ๊ฐ ์š”์†Œ์— ๋Œ€ํ•ด ์ƒ์ˆ˜ ์‹œ๊ฐ„ ์—ฐ์‚ฐ๋งŒ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
* - ๊ณต๊ฐ„ ๋ณต์žก๋„: O(1)
* ์ถ”๊ฐ€์ ์ธ ๋ฐฐ์—ด์ด๋‚˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ๋‘ ๊ฐœ์˜ ๋ณ€์ˆ˜๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
*/
function maxProfit(prices) {
let min_price = Infinity; // ํ˜„์žฌ๊นŒ์ง€์˜ ์ตœ์†Œ ๋งค์ˆ˜ ๊ฐ€๊ฒฉ (์ดˆ๊ธฐ๊ฐ’์€ ๋ฌดํ•œ๋Œ€)
let max_profit = 0; // ํ˜„์žฌ๊นŒ์ง€์˜ ์ตœ๋Œ€ ์ด์ต (์ดˆ๊ธฐ๊ฐ’์€ 0)

// ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉฐ ์ตœ์†Œ ๋งค์ˆ˜ ๊ฐ€๊ฒฉ๊ณผ ์ตœ๋Œ€ ์ด์ต์„ ๊ณ„์‚ฐ
for (let price of prices) {
if (price < min_price) {
// ํ˜„์žฌ ์ฃผ์‹ ๊ฐ€๊ฒฉ์ด ์ตœ์†Œ ๋งค์ˆ˜ ๊ฐ€๊ฒฉ๋ณด๋‹ค ์ž‘์œผ๋ฉด ์ตœ์†Œ ๋งค์ˆ˜ ๊ฐ€๊ฒฉ ๊ฐฑ์‹ 
min_price = price;
} else if (price - min_price > max_profit) {
// ํ˜„์žฌ ์ฃผ์‹ ๊ฐ€๊ฒฉ์—์„œ ์ตœ์†Œ ๋งค์ˆ˜ ๊ฐ€๊ฒฉ์„ ๋บ€ ๊ฐ’(ํ˜„์žฌ ์ด์ต)์ด ์ตœ๋Œ€ ์ด์ต๋ณด๋‹ค ํฌ๋ฉด ์ตœ๋Œ€ ์ด์ต ๊ฐฑ์‹ 
max_profit = price - min_price;
}
}

return max_profit; // ์ตœ๋Œ€ ์ด์ต ๋ฐ˜ํ™˜
}

console.log(maxProfit([7, 1, 5, 3, 6, 4])); // 5
console.log(maxProfit([7, 6, 4, 3, 1])); // 0
67 changes: 67 additions & 0 deletions encode-and-decode-strings/lledellebell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
*
* @problem
* ๋ฌธ์ž์—ด ๋ฐฐ์—ด์„ ๋‹จ์ผ ๋ฌธ์ž์—ด๋กœ ์ธ์ฝ”๋”ฉํ•˜๊ณ ,
* ๋‹ค์‹œ ์›๋ž˜์˜ ๋ฌธ์ž์—ด ๋ฐฐ์—ด๋กœ ๋””์ฝ”๋”ฉํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
*
* @example
* const encoded = encode(["hello", "world"]);
* console.log(encoded); // "5?hello5?world"
* const decoded = decode(encoded);
* console.log(decoded); // ["hello", "world"]
*
* @complexity
* - ์‹œ๊ฐ„ ๋ณต์žก๋„:
* ใ„ด encode: O(n) (n์€ ๋ฌธ์ž์—ด ๋ฐฐ์—ด์˜ ์ด ๊ธธ์ด)
* ใ„ด decode: O(n) (n์€ ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด์˜ ๊ธธ์ด)
* - ๊ณต๊ฐ„ ๋ณต์žก๋„:
* ใ„ด encode: O(1) (์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ์—†์Œ)
* ใ„ด decode: O(1) (๊ฒฐ๊ณผ ๋ฐฐ์—ด์„ ์ œ์™ธํ•œ ์ถ”๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ์—†์Œ)
*/

/**
* @param {string[]} strs - ์ธ์ฝ”๋”ฉํ•  ๋ฌธ์ž์—ด ๋ฐฐ์—ด
* @returns {string} - ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด
*/
const encode = (strs) => {
let encoded = '';
for (const str of strs) {
// ๋ฌธ์ž์—ด์„ "๊ธธ์ด?๋ฌธ์ž์—ด" ํ˜•์‹์œผ๋กœ ์ถ”๊ฐ€
encoded += `${str.length}?${str}`;
}
return encoded;
};

/**
* @param {string} s - ์ธ์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด
* @returns {string[]} - ๋””์ฝ”๋”ฉ๋œ ๋ฌธ์ž์—ด ๋ฐฐ์—ด
*/
const decode = (s) => {
const result = [];
let i = 0;

while (i < s.length) {
// ํ˜„์žฌ ์œ„์น˜์—์„œ ์ˆซ์ž(๊ธธ์ด)๋ฅผ ์ฝ์Œ
let length = 0;
while (s[i] !== '?') {
length = length * 10 + (s[i].charCodeAt(0) - '0'.charCodeAt(0)); // ์ˆซ์ž ๊ณ„์‚ฐ
i++;
}

// '?' ์ดํ›„์˜ ๋ฌธ์ž์—ด์„ ์ถ”์ถœ
i++; // '?'๋ฅผ ๊ฑด๋„ˆ๋œ€
const str = s.substring(i, i + length);
result.push(str);

// ๋‹ค์Œ ๋ฌธ์ž์—ด๋กœ ์ด๋™
i += length;
}

return result;
};

const encoded = encode(["hello", "world"]);
console.log(encoded); // "5?hello5?world"

const decoded = decode(encoded);
console.log(decoded); // ["hello", "world"]
52 changes: 52 additions & 0 deletions group-anagrams/lledellebell.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
*
* @problem
* ๋ฌธ์ž์—ด ๋ฐฐ์—ด์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, ์• ๋„ˆ๊ทธ๋žจ๋ผ๋ฆฌ ๊ทธ๋ฃนํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
*
* (์ฐธ๊ณ )
* ์• ๋„ˆ๊ทธ๋žจ(Anagram)์ด๋ž€ ๋‹จ์–ด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฌธ์ž์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟ”์„œ ๋‹ค๋ฅธ ๋‹จ์–ด๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
* ์˜ˆ๋ฅผ ๋“ค์–ด, "eat", "tea", "ate"๋Š” ๋ชจ๋‘ ๊ฐ™์€ ๋ฌธ์ž๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์• ๋„ˆ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.
*
* @constraints
* - 1 <= strs.length <= 104
* - 0 <= strs[i].length <= 100
* - strs[i]๋Š” ์†Œ๋ฌธ์ž ์•ŒํŒŒ๋ฒณ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
*
* @param {string[]} strs - ์ž…๋ ฅ ๋ฌธ์ž์—ด ๋ฐฐ์—ด
* @returns {string[][]} ์• ๋„ˆ๊ทธ๋žจ ๊ทธ๋ฃน์œผ๋กœ ๋ฌถ์ธ 2์ฐจ์› ๋ฌธ์ž์—ด ๋ฐฐ์—ด
*
* @example
* groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]); // [["bat"], ["nat", "tan"], ["ate", "eat", "tea"]]
* groupAnagrams([""]); // [[""]]
* groupAnagrams(["a"]); // [["a"]]
*
* @description
* - ๊ฐ ๋ฌธ์ž์—ด์„ ์ •๋ ฌํ•˜์—ฌ ๋™์ผํ•œ ๋ฌธ์ž๋ฅผ ๊ฐ€์ง„ ๋ฌธ์ž์—ด๋“ค์„ ๊ทธ๋ฃนํ™”ํ•ฉ๋‹ˆ๋‹ค.
* - ์ •๋ ฌ๋œ ๋ฌธ์ž์—ด์„ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด์‹œ๋งต(Map)์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
* - ์ตœ์ข…์ ์œผ๋กœ ํ•ด์‹œ๋งต์˜ ๊ฐ’๋“ค๋งŒ ์ถ”์ถœํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
*
* @complexity
* - ์‹œ๊ฐ„ ๋ณต์žก๋„: O(N * K log K)
* ใ„ด N: ์ž…๋ ฅ ๋ฌธ์ž์—ด ๋ฐฐ์—ด์˜ ๊ธธ์ด
* ใ„ด K: ๊ฐ ๋ฌธ์ž์—ด์˜ ํ‰๊ท  ๊ธธ์ด
* ๊ฐ ๋ฌธ์ž์—ด์„ ์ •๋ ฌํ•˜๋Š” ๋ฐ O(K log K)์˜ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜๋ฉฐ, ์ด๋ฅผ N๋ฒˆ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.
* - ๊ณต๊ฐ„ ๋ณต์žก๋„: O(N * K)
* ํ•ด์‹œ๋งต์— ์ €์žฅ๋˜๋Š” ํ‚ค์™€ ๊ฐ’์˜ ์ด ๊ธธ์ด์— ๋น„๋ก€ํ•ฉ๋‹ˆ๋‹ค.
*/
function groupAnagrams(strs: string[]): string[][] {
const anagrams = new Map<string, string[]>();

for (const str of strs) {
const key = str.split('').sort().join('');
if (!anagrams.has(key)) {
anagrams.set(key, []);
}
anagrams.get(key)!.push(str);
}

return Array.from(anagrams.values());
}

console.log(groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"])); // [["bat"], ["nat", "tan"], ["ate", "eat", "tea"]]
console.log(groupAnagrams([""])); // [[""]]
console.log(groupAnagrams(["a"])); // [["a"]]
120 changes: 120 additions & 0 deletions implement-trie-prefix-tree/lledellebell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/**
* @problem
* Trie๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
* - ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ตœ์ ํ™”ํ•˜๋ฉด์„œ ์ •ํ™•ํ•œ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
*
* @constraints
* - word์™€ prefix์˜ ๊ธธ์ด๋Š” ์ตœ์†Œ 1, ์ตœ๋Œ€ 2000์ž…๋‹ˆ๋‹ค.
* - word์™€ prefix๋Š” ์†Œ๋ฌธ์ž ์˜์–ด ์•ŒํŒŒ๋ฒณ(a-z)๋งŒ์œผ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
* - insert, search, startsWith ํ•จ์ˆ˜ ํ˜ธ์ถœ์€ ์ด 30,000๋ฒˆ์„ ๋„˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
*
* @example
* const trie = new Trie();
* trie.insert("apple"); // undefined
* trie.search("apple"); // true
* trie.search("app"); // false
* trie.startsWith("app"); // true
* trie.insert("app"); // undefined
* trie.search("app"); // true
*
* @complexity
* - ์‹œ๊ฐ„๋ณต์žก๋„:
* ใ„ด insert: O(m) (m์€ ๋‹จ์–ด ๊ธธ์ด)
* ใ„ด search: O(m) (m์€ ๋‹จ์–ด ๊ธธ์ด)
* ใ„ด startsWith: O(m) (m์€ ์ ‘๋‘์‚ฌ ๊ธธ์ด)
* - ๊ณต๊ฐ„๋ณต์žก๋„: O(ALPHABET_SIZE * m * n)
* ใ„ด ALPHABET_SIZE: ๋ฌธ์ž์—ด์˜ ์•ŒํŒŒ๋ฒณ ์ˆ˜ (์˜๋ฌธ์˜ ๊ฒฝ์šฐ 26)
* ใ„ด m: ๋‹จ์–ด์˜ ํ‰๊ท  ๊ธธ์ด
*/
class TrieNode {
constructor() {
// ๊ฐ ๋ฌธ์ž๋ฅผ ํ‚ค๋กœ ํ•˜๊ณ  ์ž์‹ ๋…ธ๋“œ๋ฅผ ๊ฐ’์œผ๋กœ ํ•˜๋Š” ๊ฐ์ฒด
this.children = {};
// ํ˜„์žฌ ๋…ธ๋“œ๊ฐ€ ๋‹จ์–ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž์ธ์ง€ ํ‘œ์‹œํ•˜๋Š” ํ”Œ๋ž˜๊ทธ
this.isEndOfWord = false;
}
}

class Trie {
constructor() {
// ๋นˆ ๋ฌธ์ž์—ด์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฃจํŠธ ๋…ธ๋“œ ์ƒ์„ฑ
this.root = new TrieNode();
}

/**
* ๋‹จ์–ด๋ฅผ Trie์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฉ”์„œ๋“œ
* @param {string} word - ์‚ฝ์ž…ํ•  ๋‹จ์–ด
*/
insert(word) {
// ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘
let node = this.root;

// ๋‹จ์–ด์˜ ๊ฐ ๋ฌธ์ž๋ฅผ ์ˆœํšŒ
for (let i = 0; i < word.length; i++) {
const char = word[i];
// ํ˜„์žฌ ๋ฌธ์ž์— ๋Œ€ํ•œ ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ
if (!(char in node.children)) {
node.children[char] = new TrieNode();
}
// ๋‹ค์Œ ๋ฌธ์ž๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ž์‹ ๋…ธ๋“œ๋กœ ์ด๋™
node = node.children[char];
}
// ๋‹จ์–ด์˜ ๋งˆ์ง€๋ง‰ ๋ฌธ์ž์ž„์„ ํ‘œ์‹œ
node.isEndOfWord = true;
}


/**
* ์ •ํ™•ํ•œ ๋‹จ์–ด๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฉ”์„œ๋“œ
* @param {string} word - ๊ฒ€์ƒ‰ํ•  ๋‹จ์–ด
* @returns {boolean} - ๋‹จ์–ด ์กด์žฌ ์—ฌ๋ถ€
*/
search(word) {
// ๋‹จ์–ด๋ฅผ ์ฐพ์•„ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜
const node = this._traverse(word);
// ๋‹จ์–ด๊ฐ€ ์กด์žฌํ•˜๊ณ  ํ•ด๋‹น ๋…ธ๋“œ๊ฐ€ ๋‹จ์–ด์˜ ๋์ธ ๊ฒฝ์šฐ์—๋งŒ true ๋ฐ˜ํ™˜
return node !== null && node.isEndOfWord;
}

/**
* ์ฃผ์–ด์ง„ ์ ‘๋‘์‚ฌ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋‹จ์–ด๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฉ”์„œ๋“œ
* @param {string} prefix - ๊ฒ€์ƒ‰ํ•  ์ ‘๋‘์‚ฌ
* @returns {boolean} - ์ ‘๋‘์‚ฌ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋‹จ์–ด ์กด์žฌ ์—ฌ๋ถ€
*/
startsWith(prefix) {
// ์ ‘๋‘์‚ฌ์— ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€๋งŒ ํ™•์ธ
return this._traverse(prefix) !== null;
}

/**
* ๋ฌธ์ž์—ด์„ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‚ด๋ถ€ ํ—ฌํผ ๋ฉ”์„œ๋“œ
* @param {string} str - ํƒ์ƒ‰ํ•  ๋ฌธ์ž์—ด
* @returns {TrieNode|null} - ๋งˆ์ง€๋ง‰ ๋ฌธ์ž์— ํ•ด๋‹นํ•˜๋Š” ๋…ธ๋“œ ๋˜๋Š” null
* @private
*/
_traverse(str) {
// ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ์‹œ์ž‘
let node = this.root;

// ๋ฌธ์ž์—ด์˜ ๊ฐ ๋ฌธ์ž๋ฅผ ์ˆœํšŒ
for (let i = 0; i < str.length; i++) {
const char = str[i];
// ํ˜„์žฌ ๋ฌธ์ž์— ๋Œ€ํ•œ ๋…ธ๋“œ๊ฐ€ ์—†์œผ๋ฉด null ๋ฐ˜ํ™˜
if (!(char in node.children)) {
return null;
}
// ๋‹ค์Œ ๋ฌธ์ž๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ž์‹ ๋…ธ๋“œ๋กœ ์ด๋™
node = node.children[char];
}
// ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ ๋ฐ˜ํ™˜
return node;
}
}

const trie = new Trie();
console.log(trie.insert("apple")); // undefined
console.log(trie.search("apple")); // true
console.log(trie.search("app")); // false
console.log(trie.startsWith("app")); // true
console.log(trie.insert("app")); // undefined
console.log(trie.search("app")); // true
74 changes: 74 additions & 0 deletions word-break/lledellebell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* @problem
* ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด s๊ฐ€ ๋‹จ์–ด ์‚ฌ์ „ wordDict์— ํฌํ•จ๋œ ๋‹จ์–ด๋“ค๋กœ๋งŒ ๊ตฌ์„ฑ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.
* ๋‹จ์–ด ์‚ฌ์ „์˜ ๋‹จ์–ด๋“ค์€ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฌธ์ž์—ด s๋ฅผ ์™„์ „ํžˆ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
*
* @constraints
* - 1 <= s.length <= 300
* - 1 <= wordDict.length <= 1000
* - 1 <= wordDict[i].length <= 20
* - s์™€ wordDict[i]๋Š” ๋ชจ๋‘ ์†Œ๋ฌธ์ž ์•ŒํŒŒ๋ฒณ์œผ๋กœ๋งŒ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.
*
* @param {string} s - ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด
* @param {string[]} wordDict - ๋‹จ์–ด ์‚ฌ์ „
* @returns {boolean} ๋ฌธ์ž์—ด s๊ฐ€ ๋‹จ์–ด ์‚ฌ์ „์˜ ๋‹จ์–ด๋“ค๋กœ๋งŒ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋Š”์ง€ ์—ฌ๋ถ€
*
* @example
* - ์˜ˆ์ œ 1:
* ใ„ด Input: s = "leetcode", wordDict = ["leet", "code"]
* ใ„ด Output: true
* ใ„ด Explanation: "leetcode"๋Š” "leet" + "code"๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* - ์˜ˆ์ œ 2:
* ใ„ด Input: s = "applepenapple", wordDict = ["apple", "pen"]
* ใ„ด Output: true
* ใ„ด Explanation: "applepenapple"๋Š” "apple" + "pen" + "apple"๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* - ์˜ˆ์ œ 3:
* ใ„ด Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
* ใ„ด Output: false
* ใ„ด Explanation: "catsandog"๋Š” wordDict์˜ ๋‹จ์–ด๋“ค๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
*
* @complexity
* - ์‹œ๊ฐ„ ๋ณต์žก๋„: O(n^2)
* ใ„ด ์™ธ๋ถ€ ๋ฐ˜๋ณต๋ฌธ: ๋ฌธ์ž์—ด s์˜ ๊ธธ์ด n์— ๋Œ€ํ•ด 1๋ถ€ํ„ฐ n๊นŒ์ง€ ๋ฐ˜๋ณต (O(n))
* ใ„ด ๋‚ด๋ถ€ ๋ฐ˜๋ณต๋ฌธ: ๊ฐ i์— ๋Œ€ํ•ด ์ตœ๋Œ€ i๋ฒˆ ๋ฐ˜๋ณต (O(n))
* ใ„ด substring ๋ฐ Set ๊ฒ€์ƒ‰: O(1) (substring์€ ๋‚ด๋ถ€์ ์œผ๋กœ O(k)์ด์ง€๋งŒ, k๋Š” ์ตœ๋Œ€ ๋‹จ์–ด ๊ธธ์ด๋กœ ๊ฐ„์ฃผ)
* ใ„ด ๊ฒฐ๊ณผ์ ์œผ๋กœ O(n^2)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง
* - ๊ณต๊ฐ„ ๋ณต์žก๋„: O(n + m)
* ใ„ด dp ๋ฐฐ์—ด์˜ ํฌ๊ธฐ: s์˜ ๊ธธ์ด n + 1 (O(n))
* ใ„ด wordSet: wordDict์˜ ๋‹จ์–ด ๊ฐœ์ˆ˜์— ๋น„๋ก€ (O(m), m์€ wordDict์˜ ๋‹จ์–ด ์ˆ˜)
*/
function wordBreak(s, wordDict) {
// wordDict๋ฅผ Set์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๊ฒ€์ƒ‰ ์†๋„๋ฅผ O(1)๋กœ ๋งŒ๋“ฆ
const wordSet = new Set(wordDict);

// dp ๋ฐฐ์—ด ์ƒ์„ฑ: dp[i]๋Š” s์˜ ์ฒ˜์Œ๋ถ€ํ„ฐ i๋ฒˆ์งธ ๋ฌธ์ž๊นŒ์ง€๊ฐ€ wordDict์˜ ๋‹จ์–ด๋“ค๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ„
const dp = new Array(s.length + 1).fill(false);
dp[0] = true; // ๋นˆ ๋ฌธ์ž์—ด์€ ํ•ญ์ƒ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Œ

// i๋Š” ๋ฌธ์ž์—ด์˜ ๋ ์ธ๋ฑ์Šค๋ฅผ ๋‚˜ํƒ€๋ƒ„
for (let i = 1; i <= s.length; i++) {
// j๋Š” ๋ฌธ์ž์—ด์˜ ์‹œ์ž‘ ์ธ๋ฑ์Šค๋ฅผ ๋‚˜ํƒ€๋ƒ„
for (let j = 0; j < i; j++) {
// dp[j]๊ฐ€ true์ด๊ณ , s[j:i]๊ฐ€ wordSet์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค๋ฉด
if (dp[j] && wordSet.has(s.substring(j, i))) {
dp[i] = true; // dp[i]๋ฅผ true๋กœ ์„ค์ •
break; // ๋” ์ด์ƒ ํ™•์ธํ•  ํ•„์š” ์—†์Œ
}
}
}

// dp[s.length]๊ฐ€ true๋ผ๋ฉด ๋ฌธ์ž์—ด s๋ฅผ wordDict์˜ ๋‹จ์–ด๋“ค๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Œ
return dp[s.length];
}

const s1 = "leetcode";
const wordDict1 = ["leet", "code"];
console.log(wordBreak(s1, wordDict1)); // true

const s2 = "applepenapple";
const wordDict2 = ["apple", "pen"];
console.log(wordBreak(s2, wordDict2)); // true

const s3 = "catsandog";
const wordDict3 = ["cats", "dog", "sand", "and", "cat"];
console.log(wordBreak(s3, wordDict3)); // false

0 comments on commit f244f24

Please sign in to comment.