-
-
Notifications
You must be signed in to change notification settings - Fork 245
[박종훈] 9주차 답안 제출 #156
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
[박종훈] 9주차 답안 제출 #156
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
9715128
week9 mission - Design Add and Search Words Data Structure
dev-jonghoonpark a36214c
week9 mission - Clone Graph
dev-jonghoonpark b2c1388
week9 mission - Number of Islands
dev-jonghoonpark c93bf82
week9 mission - Pacific Atlantic Water Flow
dev-jonghoonpark a99c988
week9 mission - Course Schedule
dev-jonghoonpark fad9b25
fix indent
dev-jonghoonpark File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
- 문제: https://leetcode.com/problems/clone-graph/ | ||
- 풀이: https://algorithm.jonghoonpark.com/2024/02/13/leetcode-133 | ||
|
||
```java | ||
class Solution { | ||
public Node cloneGraph(Node node) { | ||
return cloneGraph(new HashMap<>(), node); | ||
} | ||
|
||
private Node cloneGraph(Map<Integer, Node> map, Node node) { | ||
if(node == null) { | ||
return null; | ||
} | ||
|
||
if (map.containsKey(node.val)) { | ||
return map.get(node.val); | ||
} | ||
|
||
Node copy = new Node(node.val); | ||
map.put(node.val, copy); | ||
|
||
for (int i = 0; i < node.neighbors.size(); i++) { | ||
Node neighborNode = node.neighbors.get(i); | ||
copy.neighbors.add(map.getOrDefault(neighborNode.val, cloneGraph(map, node.neighbors.get(i)))); | ||
} | ||
|
||
return copy; | ||
} | ||
} | ||
``` | ||
|
||
### TC, SC | ||
|
||
node(vertex)의 수를 `V`, edge의 수를 `E` 라고 하였을 때 각 노드 마다 edge의 수만큼 반복을 해야한다. | ||
시간 복잡도는 `O(V + E)` 이다. 공간 복잡도는 `O(V)`이다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
- 문제: https://leetcode.com/problems/course-schedule/ | ||
- 풀이: https://algorithm.jonghoonpark.com/2024/03/01/leetcode-207 | ||
|
||
```java | ||
public class Solution { | ||
public boolean canFinish(int numCourses, int[][] prerequisites) { | ||
if (prerequisites.length == 0) { | ||
return true; | ||
} | ||
|
||
Map<Integer, Node> vertexMap = new HashMap<>(); | ||
|
||
for (int[] prerequisite : prerequisites) { | ||
vertexMap.putIfAbsent(prerequisite[0], new Node(prerequisite[0])); | ||
vertexMap.putIfAbsent(prerequisite[1], new Node(prerequisite[1])); | ||
|
||
Node vertex1 = vertexMap.get(prerequisite[0]); | ||
Node vertex2 = vertexMap.get(prerequisite[1]); | ||
|
||
vertex1.edges.add(vertex2); | ||
vertex2.reversedEdges.add(vertex1); | ||
} | ||
|
||
Deque<Integer> deque = new LinkedList<>(); | ||
|
||
int[] degrees = new int[numCourses]; | ||
for (int i = 0; i < degrees.length; i++) { | ||
Node vertex = vertexMap.get(i); | ||
if (vertex != null) { | ||
degrees[i] = vertex.edges.size(); | ||
if (degrees[i] == 0) { | ||
deque.addLast(i); | ||
} | ||
} | ||
} | ||
|
||
while(!deque.isEmpty()) { | ||
int vertexId = deque.removeFirst(); | ||
Node vertex = vertexMap.get(vertexId); | ||
for (Node node : vertex.reversedEdges) { | ||
degrees[node.id]--; | ||
if (degrees[node.id] == 0) { | ||
deque.addLast(node.id); | ||
} | ||
} | ||
vertexMap.remove(vertexId); | ||
} | ||
|
||
return vertexMap.isEmpty(); | ||
} | ||
} | ||
|
||
class Node { | ||
int id; | ||
List<Node> edges; | ||
List<Node> reversedEdges; | ||
|
||
public Node(int id) { | ||
this.id = id; | ||
edges = new ArrayList<>(); | ||
reversedEdges = new ArrayList<>(); | ||
} | ||
} | ||
``` |
198 changes: 198 additions & 0 deletions
198
design-add-and-search-words-data-structure/dev-jonghoonpark.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
- https://leetcode.com/problems/design-add-and-search-words-data-structure | ||
- https://algorithm.jonghoonpark.com/2024/06/30/leetcode-211 | ||
|
||
## brute force | ||
|
||
아슬아슬하게 통과한다. | ||
|
||
```java | ||
class WordDictionary { | ||
|
||
Set<String> wordSet; | ||
|
||
public WordDictionary() { | ||
wordSet = new HashSet<>(); | ||
} | ||
|
||
public void addWord(String word) { | ||
wordSet.add(word); | ||
} | ||
|
||
public boolean search(String word) { | ||
Deque<String> queue = new ArrayDeque<>(); | ||
queue.push(word); | ||
|
||
while (queue.getFirst().contains(".")) { | ||
String _word = queue.removeFirst(); | ||
String pre = _word.substring(0, _word.indexOf(".")); | ||
String post = _word.substring(_word.indexOf(".") + 1); | ||
|
||
for (char c = 'a'; c <= 'z'; c++) { | ||
queue.addLast(pre + c + post); | ||
} | ||
} | ||
|
||
while (!queue.isEmpty()) { | ||
String _word = queue.removeFirst(); | ||
if (wordSet.contains(_word)) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} | ||
``` | ||
|
||
### TC, SC | ||
|
||
- `.` 이 없을 때 | ||
- 시간 복잡도 : `O(1)` | ||
- 공간 복잡도 : `O(1)` | ||
- `.` 이 있을 때 | ||
- 시간 복잡도 : `O(26^N)` | ||
- 공간 복잡도 : `O(26^N)` | ||
- 여기서 N은 `.` 의 수 | ||
|
||
## trie | ||
|
||
[208. Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/) 문제 에서 사용한 Trie 재사용. | ||
|
||
```java | ||
class WordDictionary { | ||
|
||
Trie trie; // Trie 구현은 생략 | ||
|
||
public WordDictionary() { | ||
trie = new Trie(); | ||
} | ||
|
||
public void addWord(String word) { | ||
trie.insert(word); | ||
} | ||
|
||
public boolean search(String word) { | ||
if (word.contains(".")) { | ||
String pre = word.substring(0, word.indexOf(".")); | ||
String post = word.substring(word.indexOf(".") + 1); | ||
|
||
if (trie.startsWith(pre)) { | ||
for (char c = 'a'; c <= 'z'; c++) { | ||
if (search(pre + c + post)) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
return trie.search(word); | ||
} | ||
|
||
|
||
} | ||
``` | ||
|
||
### TC, SC | ||
|
||
입력된 문자열의 길이를 `L`, `.` 의 수를 `N` 이라고 하였을 때 | ||
|
||
addWord 메소드의 경우 시간 복잡도는 `O(L)`이다. | ||
search 메소드의 경우 입력된 문자열의 길이를 n 이라 하였을 때 시간 복잡도는 `O(L * 26 ^ N)`이다. | ||
|
||
공간 복잡도는 Trie 구조를 만드는데 사용된 공간이다. `insert된 문자열 길이의 평균` 를 `avg(L)`이라고 하였을 때 `O(avg(L) * 26)`이다. 26은 계수이기 때문에 생략할 수 있다. | ||
|
||
## trie 개선 | ||
|
||
이 문제에 적합하도록 search를 수정하였다. | ||
|
||
```java | ||
class WordDictionary { | ||
|
||
Trie trie; | ||
|
||
public WordDictionary() { | ||
trie = new Trie(); | ||
} | ||
|
||
public void addWord(String word) { | ||
trie.insert(word); | ||
} | ||
|
||
public boolean search(String word) { | ||
return trie.search(word); | ||
} | ||
|
||
|
||
} | ||
|
||
class Trie { | ||
|
||
Node root = new Node(); | ||
|
||
public Trie() { | ||
|
||
} | ||
|
||
public void insert(String word) { | ||
Node currentNode = root; | ||
for (char c : word.toCharArray()) { | ||
if (currentNode.nodes[c - 97] == null) { | ||
currentNode.nodes[c - 97] = new Node(); | ||
} | ||
currentNode = currentNode.nodes[c - 97]; | ||
} | ||
currentNode.val = word; | ||
} | ||
|
||
public boolean search(String word) { | ||
return search(root, word, 0); | ||
} | ||
|
||
public boolean search(Node node, String word, int index) { | ||
if (node == null) { | ||
return false; | ||
} | ||
|
||
if (node.val != null && node.val.length() == word.length()) { | ||
return true; | ||
} | ||
|
||
if (index >= word.length()) { | ||
return false; | ||
} | ||
|
||
char c = word.charAt(index); | ||
|
||
if (c == '.') { | ||
for (char _c = 'a'; _c <= 'z'; _c++) { | ||
if (search(node.nodes[_c - 97], word, index + 1)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} else if (node.nodes[c - 97] == null) { | ||
return false; | ||
} | ||
|
||
return search(node.nodes[c - 97], word, index + 1); | ||
} | ||
} | ||
|
||
class Node { | ||
String val; | ||
Node[] nodes = new Node[26]; | ||
} | ||
``` | ||
|
||
### TC, SC | ||
|
||
입력된 문자열의 길이를 `L`, `.` 의 수를 `N` 이라고 하였을 때 | ||
|
||
addWord 메소드의 경우 시간 복잡도는 `O(L)`이다. | ||
search 메소드의 경우 입력된 문자열의 길이를 n 이라 하였을 때 시간 복잡도는 `O(L * 26 ^ N)`이다. | ||
개선 전과 비교해봤을 때 표기상으로는 차이가 없으나, 불필요한 과정을 제거하게되어서 시간이 매우 단축된다. | ||
(`trie.startsWith(pre)`이 사라졌고, search의 호출 횟수가 줄어듬.) | ||
|
||
공간 복잡도는 Trie 구조를 만드는데 사용된 공간이다. `insert된 문자열 길이의 평균` 를 `avg(L)`이라고 하였을 때 `O(avg(L) * 26)`이다. 26은 계수이기 때문에 생략할 수 있다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
- 문제: https://leetcode.com/problems/number-of-islands/ | ||
- 풀이: https://algorithm.jonghoonpark.com/2024/03/31/leetcode-200 | ||
|
||
```java | ||
class Solution { | ||
public int numIslands(char[][] grid) { | ||
int w = grid.length; | ||
int h = grid[0].length; | ||
|
||
int count = 0; | ||
for (int i = 0; i < w; i++) { | ||
for (int j = 0; j < h; j++) { | ||
if (grid[i][j] == '1') { | ||
dfs(grid, i,j); | ||
count++; | ||
} | ||
} | ||
} | ||
return count; | ||
} | ||
|
||
public void dfs(char[][] grid, int i, int j) { | ||
if(i < 0 || i >= w || j < 0 || j >= h || grid[i][j] == '0') { | ||
return; | ||
} | ||
|
||
grid[i][j] = '0'; | ||
|
||
dfs(grid, i-1, j); | ||
dfs(grid, i, j-1); | ||
dfs(grid, i+1, j); | ||
dfs(grid, i, j+1); | ||
} | ||
} | ||
``` | ||
|
||
## TC, SC | ||
|
||
코드에 정의한 대로 grid의 길이를 `w`, grid[0]의 길이를 `h`로 정의했을 때, | ||
이 코드의 시간 복잡도는 O(w \* h), 공간 복잡도는 O(w \* h) 이다. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오우.. 다양한 방법으로 풀어보셨군요! 브루트포스로도 풀릴거란 생각은 못해봤네요..ㅋㅋ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
진짜 아슬아슬하게 걸치더라고요
아까 아침 미팅때 들어보니깐 다른 분은 실패하셨단것 같기도 하고... 👀