Skip to content

Commit e773cf0

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 777ffec + 76fe4b5 commit e773cf0

File tree

26 files changed

+1162
-12
lines changed

26 files changed

+1162
-12
lines changed

clone-graph/HC-kang.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* https://leetcode.com/problems/clone-graph
3+
* T.C. O(N)
4+
* S.C. O(N)
5+
*/
6+
function cloneGraph(node: _Node | null): _Node | null {
7+
if (!node) return null;
8+
9+
const map = new Map<number, _Node>();
10+
return dfs(node);
11+
12+
function dfs(node: _Node): _Node {
13+
if (map.has(node.val)) return map.get(node.val)!;
14+
15+
const newNode = new _Node(node.val);
16+
map.set(node.val, newNode);
17+
18+
for (let neighbor of node.neighbors) {
19+
newNode.neighbors.push(dfs(neighbor));
20+
}
21+
22+
return newNode;
23+
}
24+
}
25+
26+
/**
27+
* T.C. O(N)
28+
* S.C. O(N)
29+
*/
30+
function cloneGraph(node: _Node | null): _Node | null {
31+
if (!node) return null;
32+
33+
const map = new Map<number, _Node>();
34+
const stack = [node];
35+
const newNode = new _Node(node.val);
36+
map.set(node.val, newNode);
37+
38+
while (stack.length) {
39+
const node = stack.pop()!;
40+
const newNode = map.get(node.val)!;
41+
42+
for (let neighbor of node.neighbors) {
43+
if (!map.has(neighbor.val)) {
44+
stack.push(neighbor);
45+
const newNeighbor = new _Node(neighbor.val);
46+
map.set(neighbor.val, newNeighbor);
47+
}
48+
newNode.neighbors.push(map.get(neighbor.val)!);
49+
}
50+
}
51+
52+
return newNode;
53+
}
54+
55+
class _Node {
56+
val: number;
57+
neighbors: _Node[];
58+
59+
constructor(val?: number, neighbors?: _Node[]) {
60+
this.val = val === undefined ? 0 : val;
61+
this.neighbors = neighbors === undefined ? [] : neighbors;
62+
}
63+
}

clone-graph/haklee.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"""TC: O(n + e), SC: -
2+
3+
노드 개수 n개, 엣지 개수 e개
4+
5+
아이디어:
6+
문제 설명부터가 deepcopy를 하라는 것이니 내장함수를 써서 deepcopy를 해주자.
7+
8+
SC:
9+
- 내장함수가 필요한 공간들을 따로 잘 관리해주지 않을까? 아마 변수를 읽고 그대로 리턴값으로 바꿔줄듯.
10+
- 그렇다면 추가적으로 관리하는 공간은 필요 없다.
11+
12+
TC:
13+
- deepcopy는 필요한 정보를 그대로 다 deepcopy 뜰 뿐이다. 아마 node 개수 + edge 개수에 비례해서 시간이
14+
걸릴것 같다. O(n + e).
15+
"""
16+
17+
"""
18+
# Definition for a Node.
19+
class Node:
20+
def __init__(self, val = 0, neighbors = None):
21+
self.val = val
22+
self.neighbors = neighbors if neighbors is not None else []
23+
"""
24+
25+
import copy
26+
from typing import Optional
27+
28+
29+
class Solution:
30+
def cloneGraph(self, node: Optional["Node"]) -> Optional["Node"]:
31+
return copy.deepcopy(node)
32+
33+
34+
"""TC: O(e), SC: O(e)
35+
36+
노드 개수 n개, 엣지 개수 e개
37+
38+
아이디어:
39+
dfs 돌면서 노드들을 메모해두자. neighbors에 특정 노드를 추가해야 할때 메모에 있으면 바로 가져다
40+
쓰고, 없으면 새로 만들어서 메모에 노드를 추가한다.
41+
42+
SC:
43+
- 노드 총 n개가 memo에 올라간다. O(n).
44+
- 각 노드마다 neighbor가 있다. 각 edge마다 neighbor 리스트들의 총 아이템 개수에 2개씩 기여한다. O(e).
45+
- 더하면 O(n + e). 즉, 둘 중 더 큰 값이 공간복잡도를 지배한다.
46+
...고 생각하는 것이 일차적인 분석인데, 여기서 더 나아갈 수 있다.
47+
- 주어진 조건에 따르면 우리에게 주어진 그래프는 connected graph다. 즉, 엣지 개수가 n-1개 이상이다.
48+
- 즉, O(n) < O(e)가 무조건 성립하므로, O(e) < O(n + e) < O(e + e) = O(e). 즉, O(e).
49+
50+
TC:
51+
- SC와 비슷한 방식으로 분석 가능. O(e).
52+
"""
53+
54+
"""
55+
# Definition for a Node.
56+
class Node:
57+
def __init__(self, val = 0, neighbors = None):
58+
self.val = val
59+
self.neighbors = neighbors if neighbors is not None else []
60+
"""
61+
62+
from typing import Optional
63+
64+
65+
class Solution:
66+
def cloneGraph(self, node: Optional["Node"]) -> Optional["Node"]:
67+
if node is None:
68+
return node
69+
70+
memo = {}
71+
72+
def dfs(node):
73+
if node not in memo:
74+
new_node = Node(node.val, [])
75+
memo[node] = new_node
76+
new_node.neighbors = [dfs(i) for i in node.neighbors]
77+
return memo[node]
78+
79+
return dfs(node)

clone-graph/hwanmini.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// 노드 수 v, 간선 e
2+
// 시간복잡도 O(v+e)
3+
// 공간복잡도 O(v+e)
4+
5+
/**
6+
* // Definition for a _Node.
7+
* function _Node(val, neighbors) {
8+
* this.val = val === undefined ? 0 : val;
9+
* this.neighbors = neighbors === undefined ? [] : neighbors;
10+
* };
11+
*/
12+
13+
/**
14+
* @param {_Node} node
15+
* @return {_Node}
16+
*/
17+
var cloneGraph = function(node) {
18+
if (!node) return
19+
20+
const visited = new Map()
21+
visited.set(node, new _Node(node.val))
22+
23+
const que = [node]
24+
25+
while (que.length) {
26+
const curNode = que.shift()
27+
28+
for (neighbor of curNode.neighbors) {
29+
if (!visited.has(neighbor)) {
30+
visited.set(neighbor, new _Node(neighbor.val));
31+
que.push(neighbor)
32+
}
33+
34+
visited.get(curNode).neighbors.push(visited.get(neighbor))
35+
}
36+
}
37+
38+
return visited.get(node)
39+
};

clone-graph/jaejeong1.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.LinkedList;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.Queue;
7+
8+
// Definition for a Node.
9+
class Node {
10+
public int val;
11+
public List<Node> neighbors;
12+
public Node() {
13+
val = 0;
14+
neighbors = new ArrayList<Node>();
15+
}
16+
public Node(int _val) {
17+
val = _val;
18+
neighbors = new ArrayList<Node>();
19+
}
20+
public Node(int _val, ArrayList<Node> _neighbors) {
21+
val = _val;
22+
neighbors = _neighbors;
23+
}
24+
}
25+
26+
27+
class Solution {
28+
// 풀이: BFS 방식으로 그래프를 순회하면서 현재 노드에 연결된 노드들을 복제 여부에 따라 복제 또는 연결 처리해준다
29+
// TC: O(N)
30+
// SC: O(N)
31+
public Node cloneGraph(Node node) {
32+
if (node == null) {
33+
return null;
34+
}
35+
36+
Map<Node, Node> cloneMap = new HashMap<>();
37+
Node clone = new Node(node.val);
38+
cloneMap.put(node, clone);
39+
40+
Queue<Node> queue = new LinkedList<>();
41+
queue.add(node);
42+
43+
while (!queue.isEmpty()) {
44+
Node current = queue.poll();
45+
46+
for (Node neighbor : current.neighbors) {
47+
if (!cloneMap.containsKey(neighbor)) {
48+
cloneMap.put(neighbor, new Node(neighbor.val));
49+
queue.add(neighbor);
50+
}
51+
cloneMap.get(current).neighbors.add(cloneMap.get(neighbor));
52+
}
53+
}
54+
return clone;
55+
}
56+
}

clone-graph/kayden.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from typing import Optional
2+
from collections import deque
3+
4+
5+
class Solution:
6+
# 시간복잡도: O(N) node 개수: N
7+
# 공간복잡도: O(N)
8+
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
9+
if node:
10+
visited = {}
11+
copy = Node(val=node.val)
12+
visited[copy.val] = copy
13+
q = deque()
14+
q.append((copy, node))
15+
16+
while q:
17+
cur, node = q.popleft()
18+
19+
for idx, next_node in enumerate(node.neighbors):
20+
if next_node.val not in visited:
21+
new = Node(val=next_node.val)
22+
visited[new.val] = new
23+
q.append((new, next_node))
24+
cur.neighbors.append(visited[next_node.val])
25+
26+
return copy
27+
28+
return node

clone-graph/wogha95.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* TC: O(V + E)
3+
* 모든 정점를 방문하게 되고
4+
* 방문한 정점에서 연결된 간선을 queue에 추가하는 반복문을 실행합니다.
5+
* 따라서 시간복잡도는 정점 + 간선에 선형적으로 비례합니다.
6+
*
7+
* SC: O(V + E)
8+
* memory, visitedNodeVal 에서 V만큼 데이터 공간을 가집니다.
9+
* 그리고 queue에서 최대 모든 간선 갯수 * 2 만큼 갖게 됩니다.
10+
* 따라서 O(V + 2E) = O(V + E)로 계산했습니다.
11+
*
12+
* V: vertex, E: edge
13+
*/
14+
15+
/**
16+
* // Definition for a _Node.
17+
* function _Node(val, neighbors) {
18+
* this.val = val === undefined ? 0 : val;
19+
* this.neighbors = neighbors === undefined ? [] : neighbors;
20+
* };
21+
*/
22+
23+
/**
24+
* @param {_Node} node
25+
* @return {_Node}
26+
*/
27+
var cloneGraph = function (node) {
28+
if (!node) {
29+
return null;
30+
}
31+
32+
const memory = new Map();
33+
const visitedNodeVal = new Set();
34+
35+
return bfsClone(node);
36+
37+
// 1. bfs로 순회하면서 deep clone한 graph의 head를 반환
38+
function bfsClone(start) {
39+
const queue = [start];
40+
const clonedHeadNode = new _Node(start.val);
41+
memory.set(start.val, clonedHeadNode);
42+
43+
while (queue.length > 0) {
44+
const current = queue.shift();
45+
if (visitedNodeVal.has(current.val)) {
46+
continue;
47+
}
48+
49+
const clonedCurrentNode = getCloneNode(current.val);
50+
51+
for (const neighbor of current.neighbors) {
52+
const clonedNeighborNode = getCloneNode(neighbor.val);
53+
clonedCurrentNode.neighbors.push(clonedNeighborNode);
54+
55+
queue.push(neighbor);
56+
}
57+
58+
visitedNodeVal.add(current.val);
59+
}
60+
61+
return clonedHeadNode;
62+
}
63+
64+
// 2. memory에 val에 해당하는 node 반환 (없을 경우 생성)
65+
function getCloneNode(val) {
66+
if (!memory.has(val)) {
67+
const node = new _Node(val);
68+
memory.set(val, node);
69+
return node;
70+
}
71+
72+
return memory.get(val);
73+
}
74+
};

longest-common-subsequence/HC-kang.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* https://leetcode.com/problems/longest-common-subsequence
3+
* T.C. O(m * n)
4+
* S.C. O(n)
5+
*/
6+
function longestCommonSubsequence(text1: string, text2: string): number {
7+
const dp = Array.from({ length: text2.length + 1 }, () => 0);
8+
9+
for (let i = 1; i <= text1.length; i++) {
10+
let prev = 0;
11+
for (let j = 1; j <= text2.length; j++) {
12+
const temp = dp[j];
13+
if (text1[i - 1] === text2[j - 1]) {
14+
dp[j] = prev + 1;
15+
} else {
16+
dp[j] = Math.max(dp[j], dp[j - 1]);
17+
}
18+
prev = temp;
19+
}
20+
}
21+
22+
return dp[text2.length];
23+
}

0 commit comments

Comments
 (0)