Skip to content

Commit 2236316

Browse files
authored
Merge pull request #1659 from soobing/week15
[soobing] WEEK15 Solutions
2 parents 90eef3e + 2c6b6f3 commit 2236316

File tree

5 files changed

+200
-0
lines changed

5 files changed

+200
-0
lines changed

alien-dictionary/soobing.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* 문제 설명
3+
* - 주어진 단어들을 활용하여 알파벳 순서를 찾는 문제
4+
*
5+
* 아이디어
6+
* 1) 위상정렬 (👀 다음에 다시풀어보기) - Kahn's Algorithm
7+
* - 어렵다...
8+
*/
9+
function alienOrder(words: string[]): string {
10+
const graph: Map<string, Set<string>> = new Map();
11+
const inDegree: Map<string, number> = new Map(); // 간선의 갯수(첫 시작이 무엇인지 판단하기 위함)
12+
13+
// 단어들에 나오는 모든 문자를 정리 및 초기화
14+
for (const word of words) {
15+
for (const char of word) {
16+
if (!graph.has(char)) {
17+
graph.set(char, new Set());
18+
inDegree.set(char, 0);
19+
}
20+
}
21+
}
22+
23+
// 단어들을 비교해서 알파벳 간의 우선 순서(그래프의 간선) 추출
24+
for (let i = 0; i < words.length - 1; i++) {
25+
const w1 = words[i];
26+
const w2 = words[i + 1];
27+
const minLen = Math.min(w1.length, w2.length);
28+
29+
let foundDiff = false;
30+
31+
for (let j = 0; j < minLen; j++) {
32+
const c1 = w1[j];
33+
const c2 = w2[j];
34+
if (c1 !== c2) {
35+
if (!graph.get(c1)!.has(c2)) {
36+
graph.get(c1)!.add(c2);
37+
inDegree.set(c2, inDegree.get(c2)! + 1);
38+
}
39+
foundDiff = true;
40+
break;
41+
}
42+
}
43+
44+
// 사전순이 아닌 경우 빈문자열 리턴(If the order is invalid, return an empty string.)
45+
if (!foundDiff && w1.length > w2.length) return "";
46+
}
47+
48+
// BFS 위상정렬 시작
49+
const queue: string[] = [];
50+
for (const [char, degree] of inDegree.entries()) {
51+
if (degree === 0) queue.push(char);
52+
}
53+
54+
const result: string[] = [];
55+
while (queue.length > 0) {
56+
const current = queue.shift()!;
57+
result.push(current);
58+
59+
for (const neighbor of graph.get(current)!) {
60+
inDegree.set(neighbor, inDegree.get(neighbor)! - 1);
61+
if (inDegree.get(neighbor) === 0) {
62+
queue.push(neighbor);
63+
}
64+
}
65+
}
66+
67+
return result.length === inDegree.size ? result.join("") : "";
68+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* 문제 설명
3+
* - preorder(전위순회), inorder(중위순회) 배열을 통해 이진트리를 복원한다
4+
*
5+
*
6+
* 아이디어
7+
* 1) preorder 배열의 요소는 루트 노드이다, 이를 기준으로 inorder 배열을 좌우로 나눈다.
8+
* 2) 좌우로 나눈 inorder 배열의 길이를 통해 preorder 배열의 좌우 서브트리를 구한다.
9+
* 3) 이를 재귀적으로 반복한다.
10+
*/
11+
12+
class TreeNode {
13+
val: number;
14+
left: TreeNode | null;
15+
right: TreeNode | null;
16+
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
17+
this.val = val === undefined ? 0 : val;
18+
this.left = left === undefined ? null : left;
19+
this.right = right === undefined ? null : right;
20+
}
21+
}
22+
23+
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
24+
if (preorder.length === 0 || inorder.length === 0) return null;
25+
26+
const inorderIndexMap = new Map<number, number>();
27+
inorder.forEach((value, index) => inorderIndexMap.set(value, index));
28+
29+
let preorderIndex = 0;
30+
const helper = (left: number, right: number): TreeNode | null => {
31+
if (left > right) return null;
32+
const rootValue = preorder[preorderIndex++];
33+
const root = new TreeNode(rootValue);
34+
const index = inorderIndexMap.get(rootValue)!;
35+
36+
root.left = helper(left, index - 1);
37+
root.right = helper(index + 1, right);
38+
39+
return root;
40+
};
41+
42+
return helper(0, inorder.length - 1);
43+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* 문제 설명
3+
* - 주어진 문자열에서 가장긴 palindromic substring을 찾는 문제
4+
*
5+
* 아이디어
6+
* 1) palindrom을 찾는 법(중심 확장법) + 홀수ver, 짝수ver 두 가지 경우를 모두 확인
7+
* - two pointer 기법을 이용하여 확장하면서 가장 긴 palindromic substring을 찾는다.
8+
*/
9+
function longestPalindrome(s: string): string {
10+
let maxLength = 0;
11+
let start = 0;
12+
13+
const expand = (l: number, r: number) => {
14+
while (l >= 0 && r < s.length && s[l] === s[r]) {
15+
const currentLength = r - l + 1;
16+
if (currentLength > maxLength) {
17+
maxLength = currentLength;
18+
start = l;
19+
}
20+
l--;
21+
r++;
22+
}
23+
};
24+
25+
for (let i = 0; i < s.length; i++) {
26+
expand(i, i);
27+
expand(i, i + 1);
28+
}
29+
30+
return s.slice(start, start + maxLength);
31+
}

rotate-image/soobing.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* 문제 설명
3+
* - 2차원 배열을 90도 in-place로 회전하기
4+
*
5+
* 아이디어
6+
* 1) 대각선 이동 + 좌우 이동
7+
*
8+
*/
9+
/**
10+
Do not return anything, modify matrix in-place instead.
11+
*/
12+
function rotate(matrix: number[][]): void {
13+
const n = matrix.length;
14+
for (let i = 0; i < n; i++) {
15+
for (let j = i + 1; j < n; j++) {
16+
const temp = matrix[i][j];
17+
matrix[i][j] = matrix[j][i];
18+
matrix[j][i] = temp;
19+
}
20+
}
21+
22+
for (let i = 0; i < n; i++) {
23+
matrix[i].reverse();
24+
}
25+
}

subtree-of-another-tree/soobing.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* 문제 설명
3+
* - 두 개의 이진트리 중, subTree가 존재하는지 확인하는 문제
4+
*
5+
* 아이디어
6+
* 1) DFS + isSameTree 체크
7+
*/
8+
class TreeNode {
9+
val: number;
10+
left: TreeNode | null;
11+
right: TreeNode | null;
12+
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
13+
this.val = val === undefined ? 0 : val;
14+
this.left = left === undefined ? null : left;
15+
this.right = right === undefined ? null : right;
16+
}
17+
}
18+
19+
function isSameTree(tree1: TreeNode | null, tree2: TreeNode | null) {
20+
if ((tree1 && !tree2) || (!tree1 && tree2)) return false;
21+
if (tree1 === null && tree2 === null) return true;
22+
if (tree1?.val !== tree2?.val) return false;
23+
return (
24+
isSameTree(tree1?.left ?? null, tree2?.left ?? null) &&
25+
isSameTree(tree1?.right ?? null, tree2?.right ?? null)
26+
);
27+
}
28+
29+
function isSubtree(root: TreeNode | null, subRoot: TreeNode | null): boolean {
30+
if (!root) return false;
31+
if (isSameTree(root, subRoot)) return true;
32+
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);
33+
}

0 commit comments

Comments
 (0)