-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[강희찬] WEEK 15 Solution #605
Changes from all commits
5558d9c
e16fd48
606da9c
aa650bb
fbbd681
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/** | ||
* https://leetcode.com/problems/alien-dictionary | ||
* T.C. O(N * M) N: number of words, M: average length of word | ||
* S.C. O(1) 26 characters | ||
*/ | ||
function alienOrder(words: string[]): string { | ||
const graph: Record<string, Set<string>> = {}; | ||
const inDegree: Record<string, number> = {}; | ||
|
||
// Initialize the graph | ||
for (const word of words) { | ||
for (const char of word) { | ||
if (!graph[char]) { | ||
graph[char] = new Set(); | ||
inDegree[char] = 0; | ||
} | ||
} | ||
} | ||
|
||
// Build the graph | ||
for (let i = 0; i < words.length - 1; i++) { | ||
const word1 = words[i]; | ||
const word2 = words[i + 1]; | ||
|
||
// Check invalid case: if word1 is longer and is prefix of word2 | ||
if (word1.length > word2.length && word1.startsWith(word2)) { | ||
return ''; | ||
} | ||
|
||
let j = 0; | ||
while (j < Math.min(word1.length, word2.length)) { | ||
if (word1[j] !== word2[j]) { | ||
const curSet = graph[word1[j]]; | ||
if (!curSet.has(word2[j])) { | ||
curSet.add(word2[j]); | ||
inDegree[word2[j]]++; | ||
} | ||
break; | ||
} | ||
j++; | ||
} | ||
} | ||
|
||
// Topological sort | ||
const queue: string[] = []; | ||
for (const [char, degree] of Object.entries(inDegree)) { | ||
if (degree === 0) { | ||
queue.push(char); | ||
} | ||
} | ||
|
||
const result: string[] = []; | ||
while (queue.length) { | ||
const char = queue.shift(); | ||
result.push(char!); | ||
for (const next of graph[char!]) { | ||
inDegree[next]--; | ||
if (inDegree[next] === 0) { | ||
queue.push(next); | ||
} | ||
} | ||
} | ||
|
||
return result.length === Object.keys(inDegree).length // | ||
? result.join('') | ||
: ''; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* https://leetcode.com/problems/longest-palindromic-substring | ||
* T.C. O(n^2) | ||
* S.C. O(1) | ||
*/ | ||
function longestPalindrome(s: string): string { | ||
if (s.length < 2) return s; | ||
let start = 0; | ||
let end = 0; | ||
|
||
for (let i = 0; i < s.length; i++) { | ||
const len1 = expandBothSides(s, i, i); // odd | ||
const len2 = expandBothSides(s, i, i + 1); // even | ||
const len = Math.max(len1, len2); | ||
|
||
if (len > end - start) { | ||
start = i - Math.floor((len - 1) / 2); | ||
end = i + Math.floor(len / 2); | ||
} | ||
} | ||
|
||
return s.slice(start, end + 1); | ||
} | ||
|
||
function expandBothSides(s: string, left: number, right: number): number { | ||
while (0 <= left && right < s.length && s[left] === s[right]) { | ||
left--; | ||
right++; | ||
} | ||
|
||
return right - left - 1; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* https://leetcode.com/problems/rotate-image | ||
* T.C. O(n^2) | ||
* S.C. O(1) | ||
*/ | ||
function rotate(matrix: number[][]): void { | ||
const n = matrix.length; | ||
|
||
// transpose | ||
for (let i = 0; i < n; i++) { | ||
for (let j = i; j < n; j++) { | ||
[matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]; | ||
} | ||
} | ||
|
||
// reverse | ||
for (let i = 0; i < n; i++) { | ||
for (let j = 0; j < n / 2; j++) { | ||
[matrix[i][j], matrix[i][n - j - 1]] = [matrix[i][n - j - 1], matrix[i][j]]; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// class TreeNode { | ||
// val: number; | ||
// left: TreeNode | null; | ||
// right: TreeNode | null; | ||
// constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { | ||
// this.val = val === undefined ? 0 : val; | ||
// this.left = left === undefined ? null : left; | ||
// this.right = right === undefined ? null : right; | ||
// } | ||
// } | ||
|
||
/** | ||
* https://leetcode.com/problems/subtree-of-another-tree | ||
* T.C. O(n * m) | ||
* S.C. O(n) | ||
*/ | ||
function isSubtree(root: TreeNode | null, subRoot: TreeNode | null): boolean { | ||
if (!root) return false; | ||
if (isSameTree(root, subRoot)) return true; | ||
return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot); | ||
} | ||
|
||
function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean { | ||
if (!p && !q) return true; | ||
if (!p || !q) return false; | ||
Comment on lines
+24
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 혹시 한줄로 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. early return인데 24, 25줄이 서로 겹치는 부분이 있어서 조금 애매한 것 같습니다. if !p && !q 이렇게 나누면 겹치는 조건 없이 else문에서 (!p && q) || (p && !q) || (p.val != q.val) 조건을 처리하기 좋을 것 같습니다 |
||
if (p.val !== q.val) return false; | ||
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// class TreeNode { | ||
// val: number; | ||
// left: TreeNode | null; | ||
// right: TreeNode | null; | ||
// constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { | ||
// this.val = val === undefined ? 0 : val; | ||
// this.left = left === undefined ? null : left; | ||
// this.right = right === undefined ? null : right; | ||
// } | ||
// } | ||
|
||
/** | ||
* https://leetcode.com/problems/validate-binary-search-tree | ||
* T.C. O(n) | ||
* S.C. O(n) | ||
*/ | ||
function isValidBST(root: TreeNode | null): boolean { | ||
return validate(root, null, null); | ||
} | ||
|
||
function validate(node: TreeNode | null, min: number | null, max: number | null): boolean { | ||
if (!node) return true; | ||
if (min !== null && node.val <= min) return false; | ||
if (max !== null && node.val >= max) return false; | ||
return validate(node.left, min, node.val) && validate(node.right, node.val, max); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
별거 아닙니다만, 평소 알고리즘 푸는 습관이 그대로 코드에 드러난다고 생각하기 때문에 변수 명을 odd, even과 관련된 걸로 했으면 주석이 없어도 괜찮지 않았을까 싶습니다 :)