Skip to content

Commit db2f018

Browse files
authored
Merge pull request #2197 from radiantchoi/main
[radiantchoi] WEEK 06 Solutions
2 parents 1303e81 + 7dd2a8e commit db2f018

File tree

4 files changed

+178
-0
lines changed

4 files changed

+178
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function maxArea(height: number[]): number {
2+
let result = 0;
3+
let left = 0;
4+
let right = height.length - 1;
5+
6+
// 입력 원소의 갯수가 10만개까지이므로, O(n^2)은 시간초과
7+
// Two Pointer 활용
8+
while (left < right) {
9+
const leftPillar = height[left];
10+
const rightPillar = height[right];
11+
12+
// "면적"은 둘의 높이 중 적은 쪽과, 인덱스 차이를 곱한 값
13+
const area = (right - left) * Math.min(leftPillar, rightPillar);
14+
15+
result = Math.max(result, area);
16+
17+
// 투 포인터 이동 기준 - 무엇을 버리고, 무엇을 남길까?
18+
// 둘 중 높이가 더 낮은 쪽을 버리는 것이 더 많은 면적을 만들기 위한 합리적 선택
19+
if (leftPillar > rightPillar) {
20+
right--;
21+
} else {
22+
left++;
23+
}
24+
}
25+
26+
return result;
27+
};
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// 단어 검색을 위한 자료구조: Trie
2+
class WordDictionary {
3+
// 루트 노드
4+
let root: TrieNode
5+
6+
init() {
7+
root = TrieNode()
8+
}
9+
10+
func addWord(_ word: String) {
11+
// Array({String}) initializer의 반환 타입은 [Character]
12+
let spread = Array(word)
13+
var node = root
14+
15+
// 한 글자씩 순회하며 자식 노드 추가 혹은 방문
16+
for letter in spread {
17+
if let child = node.children[letter] {
18+
node = child
19+
} else {
20+
let newNode = TrieNode()
21+
node.children[letter] = newNode
22+
node = newNode
23+
}
24+
}
25+
26+
// 추가하고자 하는 단어의 마지막 글자에 해당하는 노드까지 순회했으므로, 해당 노드를 종료 노드로 설정
27+
node.isTerminating = true
28+
}
29+
30+
func search(_ word: String) -> Bool {
31+
return traverse(root, Array(word), 0)
32+
}
33+
34+
private func traverse(_ node: TrieNode, _ quote: [Character], _ starting: Int) -> Bool {
35+
// Trie의 0번째 인덱스는 아무 글자도 나타내지 않으므로, 첫 번째 글자가 곧 깊이 1의 노드에 저장
36+
// 따라서 starting이 quote.count와 같다면, 모든 글자를 체크한 것이므로 종료 노드인지 확인할 수 있음
37+
// quote.count까지 incrementing하고 바로 체크하므로, 이 이상 숫자가 커질 수 없음
38+
if starting == quote.count {
39+
return node.isTerminating
40+
}
41+
42+
let letter = quote[starting]
43+
44+
// 현재 글자가 와일드카드 문자인지 아닌지 체크하고, DFS 방식의 순회
45+
if letter == "." {
46+
var result = false
47+
48+
// 와일드카드 문자라면 모든 자식 노드를 순회하여 결과 반환
49+
for key in node.children.keys {
50+
if let child = node.children[key] {
51+
result = result || traverse(child, quote, starting + 1)
52+
}
53+
}
54+
55+
return result
56+
} else {
57+
// 와일드카드 문자가 아니라면, 일단 자식 노드에 포함되어있는지 확인
58+
guard let child = node.children[letter] else {
59+
return false
60+
}
61+
62+
// 포함되어있다면, 다음 글자를 순회하여 결과 반환
63+
return traverse(child, quote, starting + 1)
64+
}
65+
}
66+
}
67+
68+
// 각각의 트라이 노드
69+
class TrieNode {
70+
// 현재 글자에서 끝나는 단어가 있는가?
71+
var isTerminating: Bool
72+
// 자식 노드 - Character 형태로 다음 글자를 저장하므로, 노드에는 별도로 글자를 저장하지 않는다
73+
var children: [Character: TrieNode]
74+
75+
init(isTerminating: Bool = false, children: [Character: TrieNode] = [:]) {
76+
self.isTerminating = isTerminating
77+
self.children = children
78+
}
79+
}
80+
81+
/**
82+
* Your WordDictionary object will be instantiated and called as such:
83+
* let obj = WordDictionary()
84+
* obj.addWord(word)
85+
* let ret_2: Bool = obj.search(word)
86+
*/

spiral-matrix/radiantchoi.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
function spiralOrder(matrix: number[][]): number[] {
2+
let x = 0;
3+
let y = 0;
4+
5+
let result: number[] = [];
6+
const threshold = matrix.length * matrix[0].length
7+
8+
let direction = 0;
9+
const dx = [0, 1, 0, -1];
10+
const dy = [1, 0, -1, 0];
11+
let visited = Array.from({ length: matrix.length }, () => Array(matrix[0].length).fill(false))
12+
13+
while (true) {
14+
if (result.length >= threshold) {
15+
break;
16+
}
17+
18+
result.push(matrix[x][y]);
19+
visited[x][y] = true
20+
21+
const nx = x + dx[direction]
22+
const ny = y + dy[direction]
23+
24+
if (nx < 0 || nx >= matrix.length || ny < 0 || ny >= matrix[0].length || visited[nx][ny]) {
25+
direction++;
26+
27+
if (direction > 3) {
28+
direction = 0;
29+
}
30+
31+
x += dx[direction];
32+
y += dy[direction];
33+
} else {
34+
x = nx;
35+
y = ny;
36+
}
37+
}
38+
39+
return result;
40+
};

valid-parentheses/radiantchoi.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
function isValid(s: string): boolean {
2+
let stack: string[] = [];
3+
4+
// 스택에 대응하는 문자가 있다면 제거, 없다면 현재 문자를 추가
5+
for (const letter of s) {
6+
if (stack.length > 0) {
7+
const top = stack[stack.length - 1];
8+
9+
if (top === "(" && letter === ")") {
10+
stack.pop();
11+
} else if (top === "{" && letter === "}") {
12+
stack.pop();
13+
} else if (top === "[" && letter === "]") {
14+
stack.pop();
15+
} else {
16+
stack.push(letter);
17+
}
18+
} else {
19+
stack.push(letter);
20+
}
21+
}
22+
23+
// 스택에 내용물이 있는지 없는지만으로도 "Valid"한지 판별 가능
24+
return stack.length === 0;
25+
};

0 commit comments

Comments
 (0)