Skip to content

Commit e156dd5

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents e5afaa7 + 8fdb7bc commit e156dd5

File tree

31 files changed

+1342
-1
lines changed

31 files changed

+1342
-1
lines changed

.github/labeler.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,21 @@ java:
1818
- any-glob-to-any-file:
1919
- "**/*.java"
2020

21+
c:
22+
- changed-files:
23+
- any-glob-to-any-file:
24+
- "**/*.c"
25+
2126
c++:
2227
- changed-files:
2328
- any-glob-to-any-file:
2429
- "**/*.cpp"
2530

31+
c#:
32+
- changed-files:
33+
- any-glob-to-any-file:
34+
- "**/*.cs"
35+
2636
swift:
2737
- changed-files:
2838
- any-glob-to-any-file:

.github/workflows/integration.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }})
1717
success=true
1818
for file in $files; do
19-
if [ "$(tail -c 1 $file | wc -l)" -eq 0 ]; then
19+
if [ -s "$file" ] && [ "$(tail -c 1 $file | wc -l)" -eq 0 ]; then
2020
echo "- $file" >> $GITHUB_STEP_SUMMARY
2121
success=false
2222
fi

clone-graph/EGON.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from typing import Optional, TypeVar
2+
from unittest import TestCase, main
3+
4+
5+
# Definition for a Node.
6+
class Node:
7+
def __init__(self, val = 0, neighbors = None):
8+
self.val = val
9+
self.neighbors = neighbors if neighbors is not None else []
10+
11+
12+
class Solution:
13+
def cloneGraph(self, node: Optional[Node]) -> Optional[Node]:
14+
return self.solve(node)
15+
16+
"""
17+
Runtime: 42 ms (Beats 45.48%)
18+
Time Complexity: O(n)
19+
20+
Memory: 17.04 (Beats 8.15%)
21+
Space Complexity: O(n), upper bound
22+
"""
23+
def solve(self, node: Optional[Node]) -> Optional[Node]:
24+
clone_dict = {}
25+
stack = [node]
26+
visited = set()
27+
while stack:
28+
curr_node = stack.pop()
29+
visited.add(curr_node.val)
30+
if curr_node.val not in clone_dict:
31+
clone_dict[curr_node.val] = Node(val=curr_node.val)
32+
33+
for neighbor in curr_node.neighbors:
34+
if neighbor.val not in clone_dict:
35+
clone_dict[neighbor.val] = Node(val=neighbor.val)
36+
37+
if neighbor.val not in visited:
38+
clone_dict[curr_node.val].neighbors.append(clone_dict[neighbor.val])
39+
clone_dict[neighbor.val].neighbors.append(clone_dict[curr_node.val])
40+
stack.append(neighbor)
41+
42+
return clone_dict[node.val]
43+
44+
45+
class _LeetCodeTestCases(TestCase):
46+
def test_1(self):
47+
node_dict = {1: Node(1), 2: Node(2), 3: Node(3), 4: Node(4)}
48+
node_dict[1].neighbors = [node_dict[2], node_dict[4]]
49+
node_dict[2].neighbors = [node_dict[1], node_dict[3]]
50+
node_dict[3].neighbors = [node_dict[2], node_dict[4]]
51+
node_dict[4].neighbors = [node_dict[1], node_dict[3]]
52+
53+
Solution.cloneGraph(Solution(), node_dict[1])
54+
self.assertTrue("RUN")
55+
56+
57+
if __name__ == '__main__':
58+
main()

clone-graph/TonyKim9401.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// TC: O(n)
2+
// -> visit all elements once for each to clone them
3+
// SC: O(n)
4+
// -> all elements are stored in HashMap and values are limited maximum 2
5+
class Solution {
6+
private Map<Integer, Node> map = new HashMap<>();
7+
public Node cloneGraph(Node node) {
8+
if (node == null) return null;
9+
if (map.containsKey(node.val)) return map.get(node.val);
10+
11+
Node clone = new Node(node.val);
12+
map.put(clone.val, clone);
13+
14+
for (Node neighbor : node.neighbors) {
15+
clone.neighbors.add(cloneGraph(neighbor));
16+
}
17+
return clone;
18+
}
19+
}

clone-graph/flynn.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* 풀이
3+
* - BFS와 해시맵을 사용하여 풀이합니다
4+
*
5+
* Big O
6+
* - N: 주어진 노드의 개수
7+
* - E: 주어진 노드의 간선의 개수
8+
*
9+
* - Time complexity: O(E)
10+
* - 한 Node에서 다른 Node로 향하는 모든 edge를 두번씩 탐색합니다 (두 방향으로 연결되어 있기 때문)
11+
* - Space complexity: O(N)
12+
* - 해시맵에 최대 N개의 노드를 저장합니다
13+
*/
14+
15+
/*
16+
// Definition for a Node.
17+
class Node {
18+
public:
19+
int val;
20+
vector<Node*> neighbors;
21+
Node() {
22+
val = 0;
23+
neighbors = vector<Node*>();
24+
}
25+
Node(int _val) {
26+
val = _val;
27+
neighbors = vector<Node*>();
28+
}
29+
Node(int _val, vector<Node*> _neighbors) {
30+
val = _val;
31+
neighbors = _neighbors;
32+
}
33+
};
34+
*/
35+
36+
class Solution {
37+
public:
38+
Node* cloneGraph(Node* node) {
39+
if (node == nullptr) return nullptr;
40+
41+
unordered_map<Node*, Node*> node_map;
42+
node_map[node] = new Node(node->val);
43+
44+
queue<Node*> q;
45+
q.push(node);
46+
47+
while (!q.empty()) {
48+
Node* p = q.front();
49+
q.pop();
50+
51+
for (Node* neighbor : p->neighbors) {
52+
// 방문한 적이 없는 노드일 경우
53+
if (node_map.find(neighbor) == node_map.end()) {
54+
// node_map에 새로운 노드를 복제하여 추가
55+
node_map[neighbor] = new Node(neighbor->val);
56+
57+
// 큐에 추가
58+
q.push(neighbor);
59+
}
60+
61+
node_map[p]->neighbors.push_back(node_map[neighbor]);
62+
}
63+
}
64+
65+
return node_map[node];
66+
}
67+
};

clone-graph/jdalma.kt

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package leetcode_study
2+
3+
import io.kotest.matchers.shouldBe
4+
import org.junit.jupiter.api.Test
5+
import java.lang.RuntimeException
6+
import java.util.ArrayDeque
7+
import java.util.Queue
8+
9+
class `clone-graph` {
10+
11+
data class Node(var `val`: Int) {
12+
var neighbors: ArrayList<Node?> = ArrayList()
13+
}
14+
15+
fun cloneGraph(node: Node?): Node? {
16+
if (node == null) return null
17+
18+
return usingBFS(node)
19+
}
20+
21+
/**
22+
* TC: O(n), SC: O(n)
23+
*/
24+
private fun usingDFS(node: Node): Node {
25+
26+
fun dfs(node: Node, nodes: MutableMap<Int, Node>): Node {
27+
nodes[node.`val`]?.let {
28+
return it
29+
}
30+
val copy = Node(node.`val`)
31+
nodes[node.`val`] = copy
32+
33+
for (near in node.neighbors.filterNotNull()) {
34+
copy.neighbors.add(dfs(near, nodes))
35+
}
36+
37+
return copy
38+
}
39+
return dfs(node, mutableMapOf())
40+
}
41+
42+
/**
43+
* TC: O(n), SC: O(n)
44+
*/
45+
private fun usingBFS(node: Node): Node {
46+
val nodes = mutableMapOf<Int, Node>().apply {
47+
this[node.`val`] = Node(node.`val`)
48+
}
49+
val queue: Queue<Node> = ArrayDeque<Node>().apply {
50+
this.offer(node)
51+
}
52+
53+
while (queue.isNotEmpty()) {
54+
val now = queue.poll()
55+
val copy = nodes[now.`val`] ?: throw RuntimeException()
56+
for (near in now.neighbors.filterNotNull()) {
57+
if (!nodes.containsKey(near.`val`)) {
58+
nodes[near.`val`] = Node(near.`val`)
59+
queue.add(near)
60+
}
61+
copy.neighbors.add(nodes[near.`val`])
62+
}
63+
}
64+
return nodes[node.`val`] ?: Node(node.`val`)
65+
}
66+
67+
private fun fixture(): Node {
68+
val one = Node(1)
69+
val two = Node(2)
70+
val three = Node(3)
71+
val four = Node(4)
72+
73+
one.neighbors.add(two)
74+
one.neighbors.add(four)
75+
two.neighbors.add(one)
76+
two.neighbors.add(three)
77+
three.neighbors.add(two)
78+
three.neighbors.add(four)
79+
four.neighbors.add(one)
80+
four.neighbors.add(three)
81+
82+
return one
83+
}
84+
85+
@Test
86+
fun `입력받은 노드의 깊은 복사본을 반환한다`() {
87+
val actualNode = fixture()
88+
val expectNode = cloneGraph(actualNode)
89+
actualNode shouldBe expectNode
90+
91+
actualNode.`val` = 9999
92+
expectNode!!.`val` shouldBe 1
93+
}
94+
}

longest-common-subsequence/EGON.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from unittest import TestCase, main
2+
3+
4+
class Solution:
5+
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
6+
return self.solve_dp(text1, text2)
7+
8+
"""
9+
Runtime: 441 ms (Beats 85.60%)
10+
Time Complexity: O(m * n)
11+
- text1, text2의 길이를 각각 m, n이라 하면 이중 for문 조회에 O(m * n)
12+
- i. dp 배열 값 갱신에서 기존값 +1에 O(1)
13+
- ii. dp 배열 값 갱신에서 2개 항에 대한 max 연산에 O(2), upper bound
14+
> O(m * n) * O(2) ~= O(m * n)
15+
16+
Memory: 41.81 (Beats 55.93%)
17+
Space Complexity: O(m * n)
18+
> row의 길이가 n이가 col의 길이가 m인 2차원 배열 dp 사용에 O(m * n)
19+
"""
20+
def solve_dp(self, text1: str, text2: str) -> int:
21+
dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)]
22+
for idx1 in range(len(text1)):
23+
for idx2 in range(len(text2)):
24+
if text1[idx1] == text2[idx2]:
25+
dp[idx1 + 1][idx2 + 1] = dp[idx1][idx2] + 1
26+
else:
27+
dp[idx1 + 1][idx2 + 1] = max(dp[idx1 + 1][idx2], dp[idx1][idx2 + 1])
28+
29+
return dp[-1][-1]
30+
31+
32+
class _LeetCodeTestCases(TestCase):
33+
def test_1(self):
34+
text1 = "abcde"
35+
text2 = "ace"
36+
output = 3
37+
self.assertEqual(
38+
Solution().longestCommonSubsequence(text1, text2),
39+
output
40+
)
41+
42+
43+
if __name__ == '__main__':
44+
main()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// TC: O(n * m)
2+
// the length of text1 by the length of text2
3+
// SC: O(n)
4+
// both size of text1 and text2 can be the size of dp
5+
class Solution {
6+
public int longestCommonSubsequence(String text1, String text2) {
7+
int[] dp = new int[text2.length()];
8+
int output = 0;
9+
10+
for (char c : text1.toCharArray()) {
11+
int curLength = 0;
12+
13+
for (int i = 0; i < dp.length; i++) {
14+
if (curLength < dp[i]) curLength = dp[i];
15+
else if (c == text2.charAt(i)) {
16+
dp[i] = curLength + 1;
17+
output = Math.max(output, dp[i]);
18+
}
19+
}
20+
}
21+
return output;
22+
}
23+
}

0 commit comments

Comments
 (0)