-
-
Notifications
You must be signed in to change notification settings - Fork 195
[Helena] Week 10 solutions #167
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
Changes from all commits
7172ab9
10d7f88
a2c22bf
2cd3f4d
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,51 @@ | ||
// Time Complexity: O(n) | ||
// Space Complexity: O(n) | ||
|
||
class Solution { | ||
validTree(n, edges) { | ||
// initialize Union-Find data structure | ||
const parent = Array(n) | ||
.fill(0) | ||
.map((_, index) => index); | ||
const rank = Array(n).fill(1); | ||
|
||
// find function with path compression | ||
function find(x) { | ||
if (parent[x] !== x) { | ||
parent[x] = find(parent[x]); | ||
} | ||
return parent[x]; | ||
} | ||
|
||
// union function with union by rank | ||
function union(x, y) { | ||
const rootX = find(x); | ||
const rootY = find(y); | ||
if (rootX !== rootY) { | ||
if (rank[rootX] > rank[rootY]) { | ||
parent[rootY] = rootX; | ||
} else if (rank[rootX] < rank[rootY]) { | ||
parent[rootX] = rootY; | ||
} else { | ||
parent[rootY] = rootX; | ||
rank[rootX] += 1; | ||
} | ||
} else { | ||
// if rootX == rootY, there is a cycle | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
// process each edge | ||
for (const [u, v] of edges) { | ||
if (!union(u, v)) { | ||
// if union returns false, a cycle is detected | ||
return false; | ||
} | ||
} | ||
|
||
// if all unions are successful, it's a valid tree | ||
return true; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Time Complexity: O(n) | ||
// Space Complexity: O(n) | ||
|
||
var rob = function (nums) { | ||
// to rob a linear list of houses | ||
function robLinear(houses) { | ||
let prev1 = 0; | ||
let prev2 = 0; | ||
|
||
for (let money of houses) { | ||
let temp = Math.max(prev1, money + prev2); | ||
prev2 = prev1; | ||
prev1 = temp; | ||
} | ||
|
||
return prev1; | ||
} | ||
|
||
// 1. excluding the last house (rob from first to second-to-last) | ||
// 2. excluding the first house (rob from second to last) | ||
let robFirstToSecondLast = robLinear(nums.slice(0, -1)); | ||
let robSecondToLast = robLinear(nums.slice(1)); | ||
|
||
// return the maximum money | ||
return Math.max(robFirstToSecondLast, robSecondToLast); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// Time Complexity: O(n) | ||
// Space Complexity: O(n) | ||
|
||
var rob = function (nums) { | ||
// to store the maximum money that can be robbed up to each house | ||
let memo = new Array(nums.length).fill(-1); | ||
|
||
function robFrom(i) { | ||
// if the index is out of bounds, return 0 | ||
if (i >= nums.length) return 0; | ||
|
||
// 1. rob this house and move to the house two steps ahead | ||
// 2. skip this house and move to the next house | ||
// take the maximum of these two choices | ||
let result = Math.max(nums[i] + robFrom(i + 2), robFrom(i + 1)); | ||
|
||
// store the result | ||
memo[i] = result; | ||
|
||
return result; | ||
} | ||
|
||
// start robbing from the first house | ||
return robFrom(0); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Time Complexity: O(n^2) | ||
// Space Complexity: O(1) | ||
|
||
var longestPalindrome = function (s) { | ||
let start = 0, | ||
maxLength = 1; | ||
|
||
// to expand around the center and update the start and maxLength | ||
function expandAroundCenter(left, right) { | ||
while (left >= 0 && right < s.length && s[left] === s[right]) { | ||
left--; | ||
right++; | ||
} | ||
// update the start and maxLength if a longer palindrome is found | ||
if (maxLength < right - left - 1) { | ||
start = left + 1; | ||
maxLength = right - left - 1; | ||
} | ||
} | ||
|
||
// iterate through each character in the string | ||
for (let i = 0; i < s.length; i++) { | ||
// expand around the current character | ||
expandAroundCenter(i, i); | ||
// expand around the current and next character | ||
expandAroundCenter(i, i + 1); | ||
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. 같은 함수를 여기서 right를 1 더해서 한 번 더 호출하는 이유는 뭘까요? 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. 두 번째 호출에서 right를 1 더해서 호출하는 이유는 문자열 내의 두 가지 경우의 대칭 문자열을 모두 처리하기 위한 구현이에요! expandAroundCenter(i, i) 호출은 홀수 길이의 대칭 문자열을 찾기 위한 것이고, expandAroundCenter(i, i + 1) 호출은 짝수 길이의 대칭 문자열을 위한 것입니다. 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. 오 길이별로 나눠서 진행을 하신거군요 ㅎㅎ |
||
} | ||
|
||
// return the longest palindromic substring | ||
return s.substring(start, start + maxLength); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Time Complexity: O(n + m) m : number of edges | ||
// Space Complexity: O(n) | ||
|
||
class Solution { | ||
countComponents(n, edges) { | ||
// initialize the parent array where each node is its own parent initially | ||
const parent = new Array(n).fill(0).map((_, index) => index); | ||
|
||
// to find the root of a node with path compression | ||
const find = (node) => { | ||
if (parent[node] !== node) { | ||
parent[node] = find(parent[node]); | ||
} | ||
return parent[node]; | ||
}; | ||
|
||
// to union two nodes | ||
const union = (node1, node2) => { | ||
const root1 = find(node1); | ||
const root2 = find(node2); | ||
if (root1 !== root2) { | ||
parent[root1] = root2; | ||
} | ||
Comment on lines
+21
to
+23
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. 루트가 둘 중 하나이면 되니 여기에서는 크기 비교를 따로 하지 않아도 되는군요! union find 풀이법 흥미롭게 잘 보았습니다! |
||
}; | ||
|
||
// union all the edges | ||
for (let [a, b] of edges) { | ||
union(a, b); | ||
} | ||
|
||
// count the number of unique roots | ||
const uniqueRoots = new Set(); | ||
for (let i = 0; i < n; i++) { | ||
uniqueRoots.add(find(i)); | ||
} | ||
|
||
return uniqueRoots.size; | ||
} | ||
} |
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.
이렇게도 작성 가능하네요