Skip to content

Commit 0cb5510

Browse files
authored
Merge pull request #1401 from hi-rachel/main
[hi-rachel] Week 05 Solutions
2 parents d456f88 + 110cc37 commit 0cb5510

File tree

7 files changed

+253
-0
lines changed

7 files changed

+253
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# TC: O(N), SC: O(1)
2+
3+
class Solution:
4+
def maxProfit(self, prices: List[int]) -> int:
5+
max_profit = 0
6+
min_price = prices[0]
7+
8+
for price in prices:
9+
max_profit = max(price - min_price, max_profit)
10+
min_price = min(price, min_price)
11+
return max_profit
12+
13+
# TS 풀이
14+
# 배열 요소(숫자값)을 직접 순회하려면 for ... of 사용 혹은 forEach
15+
# for ... in -> 인덱스를 가져옴
16+
17+
# function maxProfit(prices: number[]): number {
18+
# let max_profit: number = 0;
19+
# let min_price: number = prices[0];
20+
21+
# for (let price of prices) {
22+
# max_profit = Math.max(max_profit, price - min_price);
23+
# min_price = Math.min(min_price, price);
24+
# }
25+
# return max_profit;
26+
# };
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# 문제: https://neetcode.io/problems/string-encode-and-decode
2+
# TC: O(N), SC: O(1)
3+
# ASCII 문자열이 아닌 이모티콘으로 구분자 선택
4+
5+
class Solution:
6+
def encode(self, strs: List[str]) -> str:
7+
return '🤍'.join(strs)
8+
9+
def decode(self, s: str) -> List[str]:
10+
return s.split('🤍')
11+
12+
# ASCII 문자열에 포함된 기호로 구분자를 써야할 때
13+
# -> 글자 수 표시
14+
class Solution:
15+
def encode(self, strs: List[str]) -> str:
16+
text = ""
17+
for str in strs:
18+
text += f"{len(str)}:{str}"
19+
return text
20+
21+
def decode(self, s: str) -> List[str]:
22+
ls, start = [], 0
23+
while start < len(s):
24+
mid = s.find(":", start)
25+
length = int(s[start : mid])
26+
word = s[mid + 1 : mid + 1 + length]
27+
ls.append(word)
28+
start = mid + 1 + length
29+
return ls
30+

group-anagrams/hi-rachel.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# TC O(N * K log K), SC O(N * K)
2+
3+
from collections import defaultdict
4+
5+
class Solution:
6+
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
7+
anagram_map = defaultdict(list)
8+
9+
for word in strs:
10+
key = ''.join(sorted(word))
11+
anagram_map[key].append(word)
12+
13+
return list(anagram_map.values())
14+

group-anagrams/hi-rachel.ts

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// TC O(N * K log K), N: 단어 수, K: 평균 단어 길이, 각 단어를 정렬
2+
// SC O(N * K)
3+
4+
/**
5+
* Array.from() => 이터러블 -> 일반 배열로 변환
6+
*/
7+
function groupAnagrams(strs: string[]): string[][] {
8+
const anagramMap: Map<string, string[]> = new Map();
9+
10+
for (const word of strs) {
11+
const key = word.split("").sort().join("");
12+
const group = anagramMap.get(key) || [];
13+
group.push(word);
14+
anagramMap.set(key, group);
15+
}
16+
return Array.from(anagramMap.values());
17+
}
18+
19+
/**
20+
* reduce 풀이
21+
*/
22+
// function groupAnagrams(strs: string[]): string[][] {
23+
// const anagramMap = strs.reduce((map, word) => {
24+
// const key = word.split("").sort().join("");
25+
// if (!map.has(key)) {
26+
// map.set(key, []);
27+
// }
28+
// map.get(key).push(word);
29+
// return map;
30+
// }, new Map<string, string[]>());
31+
32+
// return Array.from(anagramMap.values());
33+
// }
34+
35+
/** 간결한 버전
36+
* x ||= y (ES2021)
37+
* x가 falsy 값이면 y를 할당
38+
* JS에서 falsy 값 = false, 0, '', null, undefined, NaN
39+
*
40+
* Object.values() => 객체의 값들만 배열로 추출할때 사용
41+
*/
42+
// function groupAnagrams(strs: string[]): string[][] {
43+
// const anagramMap: {[key: string]: string[]} = {};
44+
45+
// strs.forEach((word) => {
46+
// const key = word.split('').sort().join('');
47+
// (anagramMap[key] ||= []).push(word);
48+
// });
49+
50+
// return Object.values(anagramMap);
51+
// }
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Trie Data Structure 구현
2+
# TC: O(n), SC: O(N)
3+
# autocomplete and spellchecker 등에 사용
4+
5+
class Node:
6+
def __init__(self, ending=False):
7+
self.children = {}
8+
self.ending = ending
9+
10+
class Trie:
11+
def __init__(self):
12+
self.root = Node(ending=True) # 노드 객체 생성
13+
14+
def insert(self, word: str) -> None:
15+
node = self.root #Trie의 최상위 노드부터 시작
16+
for ch in word:
17+
if ch not in node.children:
18+
node.children[ch] = Node() # 새로운 노드 생성
19+
node = node.children[ch]
20+
node.ending = True
21+
22+
def search(self, word: str) -> bool:
23+
node = self.root
24+
25+
for ch in word:
26+
if ch not in node.children:
27+
return False
28+
node = node.children[ch]
29+
return node.ending
30+
31+
def startsWith(self, prefix: str) -> bool:
32+
node = self.root
33+
34+
for ch in prefix:
35+
if ch not in node.children:
36+
return False
37+
node = node.children[ch]
38+
return True
39+
40+
41+
# Your Trie object will be instantiated and called as such:
42+
# obj = Trie()
43+
# obj.insert(word)
44+
# param_2 = obj.search(word)
45+
# param_3 = obj.startsWith(prefix)
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
class TrieNode {
2+
children: Map<string, TrieNode>;
3+
ending: boolean;
4+
5+
constructor(ending = false) {
6+
this.children = new Map();
7+
this.ending = ending;
8+
}
9+
}
10+
11+
class Trie {
12+
private root: TrieNode;
13+
14+
constructor() {
15+
this.root = new TrieNode(true);
16+
}
17+
18+
insert(word: string): void {
19+
let node = this.root;
20+
for (const ch of word) {
21+
if (!node.children.has(ch)) {
22+
node.children.set(ch, new TrieNode());
23+
}
24+
node = node.children.get(ch)!; // 노드 포인터를 ch로 이동
25+
}
26+
node.ending = true;
27+
}
28+
29+
search(word: string): boolean {
30+
let node = this.root;
31+
for (const ch of word) {
32+
if (!node.children.has(ch)) return false;
33+
node = node.children.get(ch)!;
34+
}
35+
return node.ending;
36+
}
37+
38+
startsWith(prefix: string): boolean {
39+
let node = this.root;
40+
for (const ch of prefix) {
41+
if (!node.children.has(ch)) return false;
42+
node = node.children.get(ch)!;
43+
}
44+
return true;
45+
}
46+
}
47+
48+
/**
49+
* Your Trie object will be instantiated and called as such:
50+
* var obj = new Trie()
51+
* obj.insert(word)
52+
* var param_2 = obj.search(word)
53+
* var param_3 = obj.startsWith(prefix)
54+
*/

word-break/hi-rachel.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// wordDict 조합으로 s를 만들 수 있는지 반환해라
2+
// TC: O(n^2) SC: O(n + m * k) => s의 길이 + (단어 수 * 평균 단어 길이)
3+
// .has(word) => O(1)
4+
5+
function wordBreak(s: string, wordDict: string[]): boolean {
6+
const wordSet = new Set(wordDict);
7+
const dp: boolean[] = Array(s.length + 1).fill(false);
8+
dp[0] = true;
9+
10+
for (let i = 1; i <= s.length; i++) {
11+
for (let j = 0; j < i; j++) {
12+
if (dp[j] && wordSet.has(s.slice(j, i))) {
13+
dp[i] = true;
14+
break;
15+
}
16+
}
17+
}
18+
return dp[s.length];
19+
}
20+
21+
// PY 풀이
22+
// class Solution:
23+
// def wordBreak(self, s: str, wordDict: List[str]) -> bool:
24+
// wordSet = set(wordDict)
25+
// dp = [False] * (len(s)+1)
26+
// dp[0] = True
27+
28+
// for i in range(1, len(s)+1):
29+
// for j in range(0, i):
30+
// if dp[j] and s[j:i] in wordSet:
31+
// dp[i] = True
32+
33+
// return dp[len(s)]

0 commit comments

Comments
 (0)