Skip to content

[Invidam] Week 09 Solutions #157

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 2 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions clone-graph/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Complexity
- Time Complexity: $O(V+E)$
- 정점의 수 V와 간선의 수 E에 대해, 모든 정점의 수 만큼 재귀호출이 일어거나 모든 간선의 수 만큼 반복문이 실행되므로 `V+E` 이다.
- Space Complexity: $O(V+E)$
- 정점의 수 V와 간선의 수 E에 대해, 모든 정점의 수 만큼 복제본들을 저장하는 배열(`copied`)가 선언되고 모든 간선의 수 만큼 배열(`Neighbors`)가 선언되므로 `V+E` 이다.

# Code
```go
func deepCopy(node *Node, copied map[int]*Node) *Node {
if node == nil {
return nil
}
copied[node.Val] = &Node{
Val: node.Val,
Neighbors: make([]*Node, len(node.Neighbors)),
}

for i := 0; i < len(node.Neighbors); i++ {
if c, found := copied[node.Neighbors[i].Val]; found {
copied[node.Val].Neighbors[i] = c
continue
}
copied[node.Val].Neighbors[i] = deepCopy(node.Neighbors[i], copied)
}

return copied[node.Val]
}

func cloneGraph(node *Node) *Node {
return deepCopy(node, make(map[int]*Node, 0))
}

```
45 changes: 45 additions & 0 deletions course-schedule/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Complexity
- Time Complexity: $O(V+E)$
- 정점 수와 간선 수인 V와 E에 대해, dfs인 `hasCycle`을 모두 호출하는 데 비용 V가 발생하고 반복문을 모두 순회하는 데 비용 E가 발생하여 총 비용 `V+E`가 발생한다.
- Space Complexity: $O(V+E)$
- 정점 수와 간선 수인 V와 E에 대해, 인접 리스트 `adj`을 선언하는 데 비용 `V+E`가 발생한다.

# Code
```go
func hasCycle(curr int, adj [][]int, visited []bool, finish []bool) bool {
if visited[curr] {
return !finish[curr]
}
visited[curr] = true

for _, next := range adj[curr] {
if hasCycle(next, adj, visited, finish) {
return true
}
}
finish[curr] = true

return false
}

func canFinish(numCourses int, prerequisites [][]int) bool {
adj := make([][]int, numCourses)
for i, _ := range adj {
adj[i] = make([]int, 0)
}
for _, prerequisite := range prerequisites {
from, to := prerequisite[0], prerequisite[1]
adj[from] = append(adj[from], to)
}

visited := make([]bool, numCourses)
finish := make([]bool, numCourses)
for from := range adj {
if hasCycle(from, adj, visited, finish) {
return false
}
}
return true
}

```
61 changes: 61 additions & 0 deletions design-add-and-search-words-data-structure/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Complexity
- AddWord
- Time Complexity: $O(n)$
- 단어의 길이 n만큼 재귀호출이 일어난다.
- Space Complexity: $O(n)$
- 단어의 길이 n만큼 재귀호출이 일어난다.
- Search
- Time Complexity: $O(n)$
- 단어의 길이 n만큼 재귀호출이 일어난다.
- Space Complexity: $O(n)$
- 단어의 길이 n만큼 재귀호출이 일어난다.
- `.`의 개수, 단어의 범위는 모두 2, 26개로 상수개라 제외했다.


# Code

```go
type WordDictionary struct {
Nodes []*WordDictionary
IsTerminated bool
}

func Constructor() WordDictionary {
return WordDictionary{Nodes: make([]*WordDictionary, 26)}
}

func (this *WordDictionary) AddWord(word string) {
if len(word) == 0 {
this.IsTerminated = true
return
}

if this.Nodes[word[0]-'a'] == nil {
newNode := Constructor()
this.Nodes[word[0]-'a'] = &newNode

}
this.Nodes[word[0]-'a'].AddWord(word[1:])
}

func (this *WordDictionary) Search(word string) bool {
if len(word) == 0 {
return this.IsTerminated
}

if word[0] == '.' {
for c := 'a'; c <= 'z'; c++ {
if this.Search(string(c) + word[1:]) {
return true
}
}
return false
}

if this.Nodes[word[0]-'a'] == nil {
return false
}
return this.Nodes[word[0]-'a'].Search(word[1:])
}

```
46 changes: 46 additions & 0 deletions number-of-islands/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Complexity
- Time Complexity: $O(M*N)$
- 모든 섬을 방문하는 경우가 최대이며, 이 때 `grid`의 행의 길이인 M, 열의 길이인 N을 곱한 M*N만큼 재귀호출이 일어난다.
- Space Complexity: $O(M*N)$
- 모든 섬의 방문 여부를 저장하기 위해 `grid`의 행의 길이인 M, 열의 길이인 N을 곱한 M*N 크기의 `visited` 배열을 선언했다.

# Code
```go
var offsets = [][]int{
{1, 0},
{-1, 0},
{0, 1},
{0, -1},
}

func update(i int, j int, grid [][]byte, visited [][]bool) {
visited[i][j] = true
for _, offset := range offsets {
ni, nj := i+offset[0], j+offset[1]
if ni < 0 || ni >= len(grid) || nj < 0 || nj >= len(grid[0]) || visited[ni][nj] || grid[ni][nj] == '0' {
continue
}
update(ni, nj, grid, visited)
}
}

func numIslands(grid [][]byte) int {
visited := make([][]bool, len(grid))
for i, _ := range visited {
visited[i] = make([]bool, len(grid[0]))
}

var cnt int
for i, row := range grid {
for j, val := range row {
if val == '0' || visited[i][j] {
continue
}
update(i, j, grid, visited)
cnt++
}
}
return cnt
}

```
61 changes: 61 additions & 0 deletions pacific-atlantic-water-flow/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Complexity
- Time Complexity: $O(R*C)$
- `heights`의 행과 열인 R과 C에 대해, 반복문과 DFS의 비용인 `R*C`가 발생한다.
- Space Complexity: $O(R*C)$
- `heights`의 행과 열인 R과 C에 대해, 방문 여부를 기록하는 배열(`pacifics`, `atlantics`)의 크기 비용인 `R*C`가 발생한다.

# Code
```go
var offsets = [][]int{
{1, 0},
{-1, 0},
{0, 1},
{0, -1},
}

func update(i int, j int, heights [][]int, visited [][]bool) {
visited[i][j] = true

for _, offset := range offsets {
ni, nj := i+offset[0], j+offset[1]

if ni < 0 || ni >= len(visited) || nj < 0 || nj >= len(visited[0]) || visited[ni][nj] || heights[i][j] > heights[ni][nj] {
continue
}
update(ni, nj, heights, visited)
}
}

func pacificAtlantic(heights [][]int) [][]int {
parcifics := make([][]bool, len(heights))
for i, _ := range parcifics {
parcifics[i] = make([]bool, len(heights[0]))
}
atlantics := make([][]bool, len(heights))
for i, _ := range atlantics {
atlantics[i] = make([]bool, len(heights[0]))
}

for i, _ := range heights {
for j, _ := range heights[0] {
if i == 0 || j == 0 {
update(i, j, heights, parcifics)
}
if i == len(heights)-1 || j == len(heights[0])-1 {
update(i, j, heights, atlantics)
}
}
}
boths := make([][]int, 0)
for i, _ := range heights {
for j, _ := range heights[0] {
if !(parcifics[i][j] && atlantics[i][j]) {
continue
}
boths = append(boths, []int{i, j})
}
}
return boths
}

```