Skip to content

[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

Merged
merged 4 commits into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions graph-valid-tree/yolophg.js
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;
}
}
26 changes: 26 additions & 0 deletions house-robber-ii/yolophg.js
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);
};
25 changes: 25 additions & 0 deletions house-robber/yolophg.js
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);
};
31 changes: 31 additions & 0 deletions longest-palindromic-substring/yolophg.js
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var longestPalindrome = function (s) {
  let maxPalindrome = '';

  // to expand around the center and update the start and maxLength
  function expandAroundCenter(center) {
    let left = center;
    let right = center;

    while (right < s.length - 1 && s[center] === s[right + 1]) {
      right++;
    }

    while (left > 0 && right < s.length - 1 && s[left - 1] === s[right + 1]) {
      left--;
      right++;
    }

    if (maxPalindrome.length < right - left + 1) {
      maxPalindrome = s.substring(left, right + 1);
    }
  }

  // iterate through each character in the string
  for (let i = 0; i < s.length; i++) {
    // expand around the current character
    expandAroundCenter(i);
  }

  // return the longest palindromic substring
  return maxPalindrome;
};

이렇게도 작성 가능하네요

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);
Copy link
Contributor

@dev-jonghoonpark dev-jonghoonpark Jul 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

같은 함수를 여기서 right를 1 더해서 한 번 더 호출하는 이유는 뭘까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

두 번째 호출에서 right를 1 더해서 호출하는 이유는 문자열 내의 두 가지 경우의 대칭 문자열을 모두 처리하기 위한 구현이에요!

expandAroundCenter(i, i) 호출은 홀수 길이의 대칭 문자열을 찾기 위한 것이고, expandAroundCenter(i, i + 1) 호출은 짝수 길이의 대칭 문자열을 위한 것입니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 길이별로 나눠서 진행을 하신거군요 ㅎㅎ
재밌는 접근인것 같습니다 : )

}

// return the longest palindromic substring
return s.substring(start, start + maxLength);
};
39 changes: 39 additions & 0 deletions number-of-connected-components-in-an-undirected-graph/yolophg.js
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
Copy link
Contributor

Choose a reason for hiding this comment

The 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;
}
}