Skip to content

Commit 5ce036a

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents c5544a8 + b87290d commit 5ce036a

File tree

383 files changed

+15011
-28
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

383 files changed

+15011
-28
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def maxProfit(self, prices: List[int]) -> int:
3+
minimum = prices[0]
4+
answer = 0
5+
for i in range(1, len(prices)):
6+
if minimum > prices[i]:
7+
minimum = prices[i]
8+
else:
9+
diff = prices[i] - minimum
10+
if answer < diff:
11+
answer = diff
12+
return answer

clone-graph/Chaedie.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
한번에 풀지 못해 다시 풀어볼 예정입니다.
3+
4+
Solution:
5+
1) oldToNew 라는 dict 를 만들어 무한루프를 방지합니다.
6+
2) newNode = Node(node.val), newNode.neighbors.append(dfs(nei)) 를 통해 clone을 구현합니다.
7+
8+
정점 V, 간선 E
9+
Time: O(V + E)
10+
Space: O(V + E)
11+
"""
12+
13+
14+
class Solution:
15+
def cloneGraph(self, root: Optional["Node"]) -> Optional["Node"]:
16+
if not root:
17+
return None
18+
oldToNew = {}
19+
20+
def dfs(node):
21+
if node in oldToNew:
22+
return oldToNew[node]
23+
24+
newNode = Node(node.val)
25+
oldToNew[node] = newNode
26+
27+
for nei in node.neighbors:
28+
newNode.neighbors.append(dfs(nei))
29+
30+
return newNode
31+
32+
return dfs(root)

clone-graph/EcoFriendlyAppleSu.kt

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package leetcode_study
2+
3+
/*
4+
* Graph Node 복사 문제
5+
* queue를 사용해 문제 해결
6+
* 새로 생성한 Node에 대해 방문처리를 하지 않을 경우 무한 Loop에 빠지게됨 -> 각 노드가 양방향을 가리키고 있기 때문.
7+
* 따라서, Map 자료구조를 사용해 Map<기존 Node, 복사 Node>의 모습으로 Key-Value 쌍으로 방문처리를 표현
8+
*
9+
* 시간 복잡도: O(n)
10+
* -> graph의 Node를 한 번씩 방문하여 복사하는 과정: O(n)
11+
* 공간 복잡도:
12+
* -> 복사된 Node를 매핑하는 Map 자료구조의 크기: O(n)
13+
* -> BFS를 사용한 queue size: O(n)
14+
* -> 새로 생성된 Node의 neighbor list: O(n)
15+
* */
16+
fun cloneGraph(node: Node?): Node? {
17+
if (node == null) return null
18+
if (node.neighbors.isEmpty()) return Node(1)
19+
20+
// Map< 기존 Node, 복사 Node>
21+
val nodeMap = mutableMapOf<Node, Node>()
22+
23+
val queue = ArrayDeque<Node>()
24+
queue.add(node)
25+
nodeMap[node] = Node(node.`val`)
26+
27+
while (queue.isNotEmpty()) {
28+
val current = queue.removeFirst()
29+
val clonedNode = nodeMap[current]!! // 현재 노드의 복제본
30+
31+
for (neighbor in current.neighbors) {
32+
if (neighbor == null) continue
33+
34+
// 해당 이웃이 아직 복사되지 않았다면 복사하여 맵에 저장하고 큐에 추가
35+
if (!nodeMap.containsKey(neighbor)) {
36+
nodeMap[neighbor] = Node(neighbor.`val`)
37+
queue.add(neighbor)
38+
}
39+
40+
// 복제된 현재 노드의 이웃 리스트에 복제된 이웃 노드를 추가
41+
// 양방향을 따질 필요 없이 내부 neighbor node list에 모든 노드가 있음
42+
clonedNode.neighbors.add(nodeMap[neighbor])
43+
}
44+
}
45+
return nodeMap[node]
46+
}
47+

clone-graph/Jeehay28.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* // Definition for a _Node.
3+
* function _Node(val, neighbors) {
4+
* this.val = val === undefined ? 0 : val;
5+
* this.neighbors = neighbors === undefined ? [] : neighbors;
6+
* };
7+
*/
8+
9+
/**
10+
* @param {_Node} node
11+
* @return {_Node}
12+
*/
13+
14+
// BFS approach
15+
// Time Complexity: O(N + E), where N is the number of nodes and E is the number of edges.
16+
// Space Complexity: O(N), due to the clones map and additional storage (queue for BFS, recursion stack for DFS).
17+
18+
var cloneGraph = function (node) {
19+
if (!node) {
20+
return null;
21+
}
22+
let clone = new Node(node.val);
23+
let clones = new Map();
24+
clones.set(node, clone);
25+
let queue = [node];
26+
while (queue.length > 0) {
27+
node = queue.shift();
28+
for (const neighbor of node.neighbors) {
29+
if (!clones.get(neighbor)) {
30+
const temp = new Node(neighbor.val);
31+
clones.set(neighbor, temp);
32+
queue.push(neighbor);
33+
}
34+
clones.get(node).neighbors.push(clones.get(neighbor));
35+
}
36+
}
37+
38+
return clone;
39+
};
40+
41+
// DFS approach
42+
// Time Complexity: O(N + E), where N is the number of nodes and E is the number of edges.
43+
// Space Complexity: O(N), due to the clones map and the recursion stack.
44+
45+
var cloneGraph = function (node) {
46+
if (!node) {
47+
return null;
48+
}
49+
50+
let clones = new Map();
51+
52+
const dfs = (node) => {
53+
if (clones.has(node)) {
54+
return clones.get(node);
55+
}
56+
let clone = new Node(node.val);
57+
clones.set(node, clone);
58+
59+
for (neighbor of node.neighbors) {
60+
clone.neighbors.push(dfs(neighbor));
61+
}
62+
63+
return clone;
64+
};
65+
66+
return dfs(node);
67+
};
68+

clone-graph/KwonNayeon.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"""
2+
Constraints:
3+
- The number of nodes in the graph is in the range [0, 100].
4+
- 1 <= Node.val <= 100
5+
- Node.val is unique for each node.
6+
- There are no repeated edges and no self-loops in the graph.
7+
- The Graph is connected and all nodes can be visited starting from the given node.
8+
9+
Shallow Copy (얕은 복사):
10+
- 노드 자체는 새로운 메모리에 복사
11+
- 하지만 neighbors는 원본 노드의 neighbors를 그대로 참조
12+
예시) 원본 Node1이 Node2를 neighbor로 가질 때
13+
복사한 CopyNode1은 새로운 노드지만
14+
CopyNode1의 neighbor는 원본의 Node2를 그대로 가리킴
15+
16+
Deep Copy (깊은 복사):
17+
- 노드는 새로운 메모리에 복사
18+
- neighbors도 모두 새로운 노드로 복사해서 연결
19+
예시) 원본 Node1이 Node2를 neighbor로 가질 때
20+
CopyNode1도 새로운 노드이고
21+
CopyNode1의 neighbor도 새로 만든 CopyNode2를 가리킴
22+
23+
Time Complexity: O(N + E)
24+
- N: 노드의 개수
25+
- E: 엣지의 개수
26+
- 모든 노드와 엣지를 한 번씩 방문
27+
28+
Space Complexity: O(N)
29+
- N: 노드의 개수
30+
- dictionary와 재귀 호출 스택 공간
31+
32+
# Definition for a Node.
33+
class Node:
34+
def __init__(self, val = 0, neighbors = None):
35+
self.val = val
36+
self.neighbors = neighbors if neighbors is not None else []
37+
38+
참고 사항:
39+
- 혼자 풀기 어려워서, 문제와 답을 이해하는 것에 집중했습니다!
40+
"""
41+
class Solution:
42+
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
43+
if not node:
44+
return None
45+
46+
dict = {}
47+
48+
def dfs(node):
49+
if node.val in dict: # 이미 복사한 노드라면
50+
return dict[node.val] # 해당 복사본 반환
51+
52+
# 새로운 노드 생성
53+
copy = Node(node.val)
54+
dict[node.val] = copy # dictionary에 기록
55+
56+
# 각 neighbor에 대해서도 같은 과정 수행
57+
for neighbor in node.neighbors:
58+
copy.neighbors.append(dfs(neighbor))
59+
60+
return copy
61+
62+
return dfs(node)
63+

clone-graph/dusunax.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'''
2+
# 133. Clone Graph
3+
This is the problem for copying nodes, which helps you understand the concept of referencing a node & copying the node (creating a new node from the existing one).
4+
5+
👉 Perform recursion DFS with the correct escape condition and handling of NoneType.
6+
'''
7+
8+
"""
9+
# Definition for a Node.
10+
class Node:
11+
def __init__(self, val = 0, neighbors = None):
12+
self.val = val
13+
self.neighbors = neighbors if neighbors is not None else []
14+
"""
15+
from typing import Optional
16+
class Solution:
17+
def cloneGraph(self, node: Optional['Node']) -> Optional['Node']:
18+
if node is None:
19+
return None
20+
21+
visited = {}
22+
23+
def DFS(currNode):
24+
if currNode.val in visited:
25+
return visited[currNode.val]
26+
27+
copiedNode = Node(currNode.val)
28+
visited[currNode.val] = copiedNode
29+
30+
for neighbor in currNode.neighbors:
31+
copiedNode.neighbors.append(DFS(neighbor))
32+
33+
return copiedNode
34+
35+
return DFS(node)

clone-graph/ekgns33.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
// Definition for a Node.
3+
class Node {
4+
public int val;
5+
public List<Node> neighbors;
6+
public Node() {
7+
val = 0;
8+
neighbors = new ArrayList<Node>();
9+
}
10+
public Node(int _val) {
11+
val = _val;
12+
neighbors = new ArrayList<Node>();
13+
}
14+
public Node(int _val, ArrayList<Node> _neighbors) {
15+
val = _val;
16+
neighbors = _neighbors;
17+
}
18+
}
19+
*/
20+
21+
class Solution {
22+
public Node cloneGraph(Node node) {
23+
Map<Integer, Node> nodeMap = new HashMap<>();
24+
if(node == null) return null;
25+
boolean[] visited = new boolean[101];
26+
dfsHelper(nodeMap, node, visited);
27+
return nodeMap.get(1);
28+
}
29+
30+
private void dfsHelper(Map<Integer, Node> map, Node node, boolean[] visited) {
31+
if(!map.containsKey(node.val)) {
32+
map.put(node.val, new Node(node.val));
33+
}
34+
visited[node.val] = true;
35+
Node cur = map.get(node.val);
36+
for(Node adjacent : node.neighbors) {
37+
map.putIfAbsent(adjacent.val, new Node(adjacent.val));
38+
cur.neighbors.add(map.get(adjacent.val));
39+
if(!visited[adjacent.val]) dfsHelper(map, adjacent, visited);
40+
}
41+
}
42+
}

clone-graph/forest000014.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
# Time Complexity: O(n * e), where e is the maximum number of edges of a node
3+
- 전체 node를 순회하면서, 그 이웃에 해당하는 복제본을 생성해서 복제본끼리 연결해준다.
4+
- 단, 중복 방문을 막기 위해, 복제본이 이미 이웃 복제본을 가지고 있는지 확인한다. 이 과정에서 O(e)만큼의 List 순회를 한다.
5+
6+
# Space Complexity: O(n)
7+
- 전체 Node 만큼의 메모리가 필요하다.
8+
(Space Complexity를 계산하기 애매한 측면이 있네요. 저는 지금까지 출력은 space complexity에 포함하지 않고 계산했었는데, 그 이유는 "어떤 알고리즘을 구현하든 출력은 동일하기 때문"인데요. 이 문제의 경우에 출력은 Node 하나이지만, 실제로는 Node 전체만큼의 메모리를 반드시 생성해야 한다는 특수성이 있습니다. 그래서 "어떻게 구현하든 동일하게 사용해야만 하는 메모리는 Space Complexity에서 배제한다" 라는 논리로만 보자면 O(1)일 것 같고, "출력을 제외한 메모리 사용은 Space Complexity에 포함한다" 라는 논리대로라면 O(n)인 것 같습니다.)
9+
10+
11+
전체 노드를 DFS로 순회하면서 이웃 노드의 복제본을 생성하여 현재 노드의 복제본과 연결을 맺어줍니다.
12+
다만, 중복 방문을 막기 위해, 복제본이 이미 이웃 복제본을 가지고 있는지 확인한다.
13+
또한 순환 참조(cycle 구조)를 막기 위해서, 복제본 노드를 생성시 단순히 new 키워드를 사용하지 않고, 별도의 map을 통해 싱글톤으로 생성한다. (각 노드의 val은 distinct하다는 점을 이용)
14+
15+
16+
// Definition for a Node.
17+
class Node {
18+
public int val;
19+
public List<Node> neighbors;
20+
public Node() {
21+
val = 0;
22+
neighbors = new ArrayList<Node>();
23+
}
24+
public Node(int _val) {
25+
val = _val;
26+
neighbors = new ArrayList<Node>();
27+
}
28+
public Node(int _val, ArrayList<Node> _neighbors) {
29+
val = _val;
30+
neighbors = _neighbors;
31+
}
32+
}
33+
*/
34+
35+
class Solution {
36+
37+
Map<Integer, Node> map = new HashMap<>();
38+
39+
public Node cloneGraph(Node node) {
40+
if (node == null) {
41+
return null;
42+
}
43+
44+
Node newNode = createNode(node.val);
45+
dfs(node);
46+
47+
return newNode;
48+
}
49+
50+
public Node createNode(int val) {
51+
if (!map.containsKey(val)) {
52+
map.put(val, new Node(val));
53+
}
54+
return map.get(val);
55+
}
56+
57+
public void dfs(Node oldNode) {
58+
Node newNode = map.get(oldNode.val);
59+
60+
for (Node oldNeighbor : oldNode.neighbors) {
61+
boolean hasIt = false;
62+
for (Node newNeighbor : newNode.neighbors) {
63+
if (newNeighbor.val == oldNeighbor.val) {
64+
hasIt = true;
65+
break;
66+
}
67+
}
68+
69+
if (!hasIt) {
70+
Node newNeighbor = createNode(oldNeighbor.val);
71+
newNode.neighbors.add(newNeighbor);
72+
newNeighbor.neighbors.add(newNode);
73+
dfs(oldNeighbor);
74+
}
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)