Skip to content

Commit 5b01c43

Browse files
authored
Merge branch 'DaleStudy:main' into main
2 parents 33f2a5e + 2a28adf commit 5b01c43

Some content is hidden

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

74 files changed

+2677
-6
lines changed

clone-graph/Geegong.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import java.util.*;
2+
3+
/*
4+
// Definition for a Node.
5+
class Node {
6+
public int val;
7+
public List<Node> neighbors;
8+
public Node() {
9+
val = 0;
10+
neighbors = new ArrayList<Node>();
11+
}
12+
public Node(int _val) {
13+
val = _val;
14+
neighbors = new ArrayList<Node>();
15+
}
16+
public Node(int _val, ArrayList<Node> _neighbors) {
17+
val = _val;
18+
neighbors = _neighbors;
19+
}
20+
}
21+
*/
22+
public class Geegong {
23+
24+
/**
25+
* dfs 방식으로 풀이
26+
* visited 로 memoization 하여 방문해서 복사가 된 노드들을 저장
27+
* 한번 방문했던 노드를 neighbors 탐색을 통해 또 방문하게 되면 visited 에서 꺼내서 return 하도록 한다.
28+
*
29+
* time complexity : O(2N) -> O(N)
30+
* space complexity : O(N)
31+
* @param node
32+
* @return
33+
*/
34+
public Node cloneGraph(Node node) {
35+
// node에 진입한 순간에 바로 visited 에 넣어서 cloned 된 node 들을 집어넣도록 관리
36+
Map<Integer, Node> visited = new HashMap<>();
37+
38+
if (node == null) {
39+
return null;
40+
}
41+
42+
Node result = cloneDeeply(node, visited);
43+
return result;
44+
}
45+
46+
public Node cloneDeeply(Node origin, Map<Integer, Node> visited) {
47+
48+
// visited 에는 cloned 된 node 들을 저장하고 있어 한번 방문했던 노드라면 복사한 노드를 리턴한다.
49+
if (visited.containsKey(origin.val)) {
50+
return visited.get(origin.val);
51+
}
52+
53+
Node clonedTarget = new Node(origin.val);
54+
visited.put(origin.val, clonedTarget);
55+
56+
for (Node neighbor : origin.neighbors) {
57+
Node clonedNeighbor = cloneDeeply(neighbor, visited);
58+
clonedTarget.neighbors.add(clonedNeighbor);
59+
}
60+
61+
return clonedTarget;
62+
}
63+
64+
65+
// 이미 다른 분들이 Node 클래스를 많이 만들어놓으셔서.. 개인 클래스 안에 이너 클래스로 Node 만듬
66+
public static class Node {
67+
public int val;
68+
public List<Node> neighbors;
69+
public Node() {
70+
val = 0;
71+
neighbors = new ArrayList<Node>();
72+
}
73+
public Node(int _val) {
74+
val = _val;
75+
neighbors = new ArrayList<Node>();
76+
}
77+
public Node(int _val, ArrayList<Node> _neighbors) {
78+
val = _val;
79+
neighbors = _neighbors;
80+
}
81+
}
82+
}
83+
84+

clone-graph/delight010.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
class Solution {
2+
// Time O(V+E)
3+
// Space O(V)
4+
func cloneGraph(_ node: Node?) -> Node? {
5+
guard let node = node else { return nil }
6+
7+
var visited: [Int: Node] = [:]
8+
var queue: [Node] = []
9+
10+
let firstNode = Node(node.val)
11+
visited[node.val] = firstNode
12+
13+
queue.append(node)
14+
15+
while !queue.isEmpty {
16+
let currentNode = queue.removeFirst()
17+
18+
for neighbor in currentNode.neighbors {
19+
guard let neighbor = neighbor else { continue }
20+
21+
if let clonedNeighbor = visited[neighbor.val] {
22+
visited[currentNode.val]!.neighbors.append(clonedNeighbor)
23+
} else {
24+
visited[neighbor.val] = Node(neighbor.val)
25+
visited[currentNode.val]!.neighbors.append(visited[neighbor.val])
26+
queue.append(neighbor)
27+
}
28+
}
29+
}
30+
31+
return firstNode
32+
}
33+
}
34+

clone-graph/hyer0705.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Definition for _Node.
3+
* class _Node {
4+
* val: number
5+
* neighbors: _Node[]
6+
*
7+
* constructor(val?: number, neighbors?: _Node[]) {
8+
* this.val = (val===undefined ? 0 : val)
9+
* this.neighbors = (neighbors===undefined ? [] : neighbors)
10+
* }
11+
* }
12+
*
13+
*/
14+
15+
function cloneGraph(node: _Node | null): _Node | null {
16+
if (!node) return null;
17+
18+
const cloned = new Map<number, _Node>();
19+
20+
const queue: _Node[] = [];
21+
22+
const copied = new _Node(node.val);
23+
cloned.set(node.val, copied);
24+
25+
queue.push(node);
26+
27+
let pointer = 0;
28+
29+
while (pointer < queue.length) {
30+
const current = queue[pointer++];
31+
32+
const copiedNode = cloned.get(current.val)!;
33+
34+
for (const neighbor of current.neighbors) {
35+
if (!cloned.has(neighbor.val)) {
36+
const copiedNeighbor = new _Node(neighbor.val);
37+
cloned.set(neighbor.val, copiedNeighbor);
38+
39+
queue.push(neighbor);
40+
}
41+
copiedNode.neighbors.push(cloned.get(neighbor.val)!);
42+
}
43+
}
44+
45+
return copied;
46+
}

clone-graph/sonjh1217.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Definition for a Node.
3+
* public class Node {
4+
* public var val: Int
5+
* public var neighbors: [Node?]
6+
* public init(_ val: Int) {
7+
* self.val = val
8+
* self.neighbors = []
9+
* }
10+
* }
11+
*/
12+
13+
class Solution {
14+
// O(V+E) time / O(V) space
15+
func cloneGraph(_ node: Node?) -> Node? {
16+
guard let node = node else {
17+
return nil
18+
}
19+
var newNodeByVal = [Int: Node]()
20+
return copy(node: node, newNodeByVal: &newNodeByVal)
21+
}
22+
23+
func copy(node: Node, newNodeByVal: inout [Int: Node]) -> Node {
24+
if let node = newNodeByVal[node.val] {
25+
return node
26+
}
27+
var newNode = Node(node.val)
28+
newNodeByVal[node.val] = newNode
29+
30+
for neighbor in node.neighbors {
31+
guard let neighbor = neighbor else {
32+
continue
33+
}
34+
let newNeighbor = copy(node: neighbor, newNodeByVal: &newNodeByVal)
35+
newNode.neighbors.append(newNeighbor)
36+
}
37+
return newNode
38+
}
39+
}

clone-graph/yhkee0404.scala

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import scala.collection.mutable.ListBuffer
2+
3+
/**
4+
* Definition for a Node.
5+
* class Node(var _value: Int) {
6+
* var value: Int = _value
7+
* var neighbors: List[Node] = List()
8+
* }
9+
*/
10+
11+
object Solution {
12+
def cloneGraph(graph: Node): Node = {
13+
if (graph == null) {
14+
return null
15+
}
16+
val dp = Array.fill[Node](101)(null)
17+
cloneGraph(dp, graph)
18+
}
19+
def cloneGraph(dp: Array[Node], graph: Node): Node = {
20+
if (dp(graph.value) != null) {
21+
return dp(graph.value)
22+
}
23+
val u = Node(graph.value)
24+
dp(graph.value) = u
25+
val neighbors = ListBuffer[Node]()
26+
graph.neighbors
27+
.foreach {
28+
neighbors += cloneGraph(dp, _)
29+
}
30+
u.neighbors ++= neighbors
31+
u
32+
}
33+
}

linked-list-cycle/jinvicky.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import java.util.HashSet;
2+
import java.util.Set;
3+
4+
public class Solution {
5+
/**
6+
* 문제에서 말하는 pos는 설명을 돕는 사이클 발생 위치이지 코드 상에서 사용하지 않는다.
7+
*/
8+
public boolean hasCycle(ListNode head) {
9+
Set<Integer> set = new HashSet<>();
10+
while(head != null) {
11+
// set에서 이미 존재하는 숫자가 있으면 바로 return true;
12+
// set.add() 메서드는 추가 성공 시 true, 이미 존재하는 숫자면 추가하지 못하고 false를 반환한다.
13+
if(!set.add(head.val)) return true;
14+
head = head.next;
15+
}
16+
return false;
17+
}
18+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import java.util.ArrayList;
2+
import java.util.Collections;
3+
import java.util.Comparator;
4+
import java.util.List;
5+
6+
public class Geegong {
7+
8+
/**
9+
* LIS, LCS 와 연관지어서 풀이
10+
* 1. 먼저 text1을 훑어보는데 text1에 중복되는 알파벳이 있을 수 있기에 각 캐릭터별로 인덱스들을 저장 (각 원소가 arrayList가 있는 배열)
11+
* 2. text2 를 훑으면서 매칭되는 캐릭터들에 대해서만 1에서 저장된 인덱스들을 한 배열안에 나열
12+
* -> 이떄 나열해서 넣을때마다 역순으로 집어넣는게 중요! (왜냐면 이 나열된 인덱스들을 가지고 LIS를 구할거라서)
13+
* 3. 나열된 인덱스들의 값들을 가지고 LIS 를 구한다, 즉 이 LIS의 길이가 LCS 의 길이가 된다..!! (와우 신기)
14+
* 그러나 leet code 에 돌렸을 때 runtime 이 영 좋지는 않음
15+
*
16+
* time complexity : O(M + N logN) => text2에 대해서 문자마다 바이너리서치가 수행됨
17+
* space complexity : O(M+N)
18+
* @param text1
19+
* @param text2
20+
* @return
21+
*/
22+
public int longestCommonSubsequence(String text1, String text2) {
23+
char[] chText1 = text1.toCharArray();
24+
char[] chText2 = text2.toCharArray();
25+
26+
// text1만 각 원소 별로 char가 가지는 index를 array 로 갖는 배열을 생성
27+
List<Integer>[] positionIndices = new List[26];
28+
for (int index = 0; index<chText1.length; index++) {
29+
if (positionIndices[chText1[index] - 'a'] == null) {
30+
positionIndices[chText1[index] - 'a'] = new ArrayList();
31+
positionIndices[chText1[index] - 'a'].add(index);
32+
} else {
33+
positionIndices[chText1[index] - 'a'].add(index);
34+
}
35+
}
36+
37+
38+
// 여기서부터 LIS 를 구할것임
39+
List<Integer> indices = new ArrayList<>();
40+
for (int index=0; index<chText2.length; index++) {
41+
42+
char find = chText2[index];
43+
if (positionIndices[find-'a'] != null && positionIndices[find-'a'].size() > 0) {
44+
// 역순 (LIS 를 구하기 위해서 일부러 뒤집어 높음, 즉 각 char 별 LIS 를 구할것이기 때문에..)
45+
// positionIndices 에서 구했던 값들을 그대로 addAll 한다면 오름차순이 되기때문에 정확한 LIS 를 구할 수 없다
46+
47+
indices.addAll(positionIndices[find-'a'].stream().sorted(Comparator.reverseOrder()).toList());
48+
}
49+
}
50+
51+
// find LIS
52+
return findLIS(indices).size();
53+
}
54+
55+
public List<Integer> findLIS(List<Integer> source) {
56+
if (source.size() == 0) {
57+
return source;
58+
}
59+
60+
List<Integer> LISResult = new ArrayList<>();
61+
for (int index=0; index<source.size(); index++) {
62+
int target = source.get(index);
63+
int insertionPosition = Collections.binarySearch(LISResult, target);
64+
//Returns:
65+
//the index of the search key, if it is contained in the list;
66+
// otherwise, (-(insertion point) - 1). The insertion point is defined as the point at which the key would be inserted into the list:
67+
if (insertionPosition < 0) {
68+
insertionPosition = -insertionPosition - 1;
69+
}
70+
71+
if (LISResult.size() == insertionPosition) {
72+
LISResult.add(target);
73+
} else {
74+
LISResult.set(insertionPosition, target);
75+
}
76+
}
77+
78+
return LISResult;
79+
}
80+
81+
}
82+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution {
2+
// Time (MN)
3+
// Space (MN)
4+
func longestCommonSubsequence(_ text1: String, _ text2: String) -> Int {
5+
var dp = Array(repeating: Array(repeating: 0, count: text2.count + 1),
6+
count: text1.count + 1)
7+
for (i, char1) in text1.enumerated() {
8+
for (j, char2) in text2.enumerated() {
9+
if char1 == char2 {
10+
dp[i + 1][j + 1] = dp[i][j] + 1
11+
} else {
12+
dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1])
13+
}
14+
}
15+
}
16+
17+
return dp[text1.count][text2.count]
18+
}
19+
}
20+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function longestCommonSubsequence(text1: string, text2: string): number {
2+
const m = text1.length;
3+
const n = text2.length;
4+
5+
const dp: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
6+
7+
for (let i = 1; i <= m; i++) {
8+
for (let j = 1; j <= n; j++) {
9+
if (text1[i - 1] === text2[j - 1]) {
10+
dp[i][j] = dp[i - 1][j - 1] + 1;
11+
} else {
12+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
13+
}
14+
}
15+
}
16+
17+
return dp[m][n];
18+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Solution {
2+
int longestCommonSubsequence(String text1, String text2) {
3+
final dp = List.generate(
4+
text1.length + 1,
5+
(_) => List.filled(text2.length + 1, 0),
6+
);
7+
for (int i = 1; i <= text1.length; i++) {
8+
for (int j = 1; j <= text2.length; j++) {
9+
dp[i][j] = text1[i - 1] == text2[j - 1] ? dp[i - 1][j - 1] + 1 : max(dp[i - 1][j], dp[i][j - 1]);
10+
}
11+
}
12+
return dp[text1.length][text2.length];
13+
}
14+
}

0 commit comments

Comments
 (0)