Skip to content

Commit 6b013ad

Browse files
committed
solve: week 08
1 parent 8cf1244 commit 6b013ad

File tree

5 files changed

+211
-0
lines changed

5 files changed

+211
-0
lines changed

combination-sum/invidam.go.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Complexity
2+
- Time complexity: $O(N^t)$
3+
- `target`의 크기 t와 `candiates`의 크기 N에 대하여, t만큼의 재귀호출이 연속적으로 일어날 수 있고 각 함수에서 배열 순회 비용 N이 발생할 수 있다.
4+
5+
- Space complexity: $O(N^t)$
6+
- `target`의 크기 t와 `candiates`의 크기 N에 대하여, 백트래킹에서 만들 수 있는 모든 경우의 수 만큼 `ret`이 적재될 수 있다.
7+
8+
# Code
9+
```go
10+
func combinationSum(candidates []int, target int) [][]int {
11+
sort.Ints(candidates)
12+
13+
var combination func(candidates []int, target int) [][]int
14+
combination = func(candidates []int, target int) [][]int {
15+
if target < 0 {
16+
return nil
17+
}
18+
if target == 0 {
19+
return [][]int{{}}
20+
}
21+
22+
ret := make([][]int, 0)
23+
for i, c := range candidates {
24+
items := combination(candidates[i:], target-c)
25+
for _, item := range items {
26+
ret = append(ret, append(item, c))
27+
}
28+
}
29+
return ret
30+
}
31+
32+
return combination(candidates, target)
33+
}
34+
35+
```
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Complexity
2+
- Time complexity: $O(n)$
3+
- 원소의 크기 n에 대하여, 캐시 선언과 최악의 경우 순회에 비용 `n`이 발생한다.
4+
5+
- Space complexity: $O(n)$
6+
- 원소의 크기 n에 대하여, 캐시 선언과 최악의 경우 순회(콜 스택)에 비용 `n`이 발생한다.
7+
# Code
8+
```go
9+
func buildTree(preorder []int, inorder []int) *TreeNode {
10+
cache := make(map[int]int)
11+
12+
find := func(arr []int, val int) int {
13+
if len(cache) == 0 {
14+
cache = make(map[int]int, len(arr))
15+
for i, v := range arr {
16+
cache[v] = i
17+
}
18+
}
19+
return cache[val]
20+
}
21+
var organize func(preorder []int, inorder []int) *TreeNode
22+
organize = func(preorder []int, inorder []int) *TreeNode {
23+
if len(preorder) == 0 {
24+
return nil
25+
}
26+
rootIdx := find(inorder, preorder[0]) - find(inorder, inorder[0])
27+
28+
return &TreeNode{
29+
Val: preorder[0],
30+
Left: organize(preorder[1:rootIdx+1], inorder[:rootIdx]),
31+
Right: organize(preorder[rootIdx+1:], inorder[rootIdx+1:]),
32+
}
33+
}
34+
35+
return organize(preorder, inorder)
36+
}
37+
38+
```
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Complexity
2+
- Insert
3+
- Time complexity: $$O(n)$$
4+
- `word`의 길이 n에 대하여, 깊이 n까지 재귀호출을 반복하는 비용이 발생한다.
5+
- Space complexity: $$O(n)$$
6+
- `word`의 길이 n에 대하여, 깊이 n까지 트라이 구조를 만드는 비용이 발생한다.
7+
- Search
8+
- Time complexity: $$O(n)$$
9+
- `word`의 길이 n에 대하여, 깊이 n까지 재귀호출을 반복하는 비용이 발생한다.
10+
- Space complexity: $$O(1)$$
11+
- 별도 비용이 발생하지 않는다.
12+
# Code
13+
```go
14+
type Trie struct {
15+
Val byte
16+
IsTerminal bool
17+
Nodes []*Trie
18+
}
19+
20+
func Constructor() Trie {
21+
return Trie{Nodes: make([]*Trie, 26)}
22+
}
23+
24+
func (this *Trie) Insert(word string) {
25+
if len(word) == 0 {
26+
27+
return
28+
}
29+
30+
if this.Nodes[word[0]-'a'] == nil {
31+
newNode := Constructor()
32+
this.Nodes[word[0]-'a'] = &newNode
33+
this.Nodes[word[0]-'a'].Val = word[0]
34+
}
35+
this.Nodes[word[0]-'a'].Insert(word[1:])
36+
}
37+
38+
func (this *Trie) Search(word string) bool {
39+
if len(word) == 0 {
40+
return this.IsTerminal
41+
}
42+
if this.Nodes[word[0]-'a'] == nil {
43+
return false
44+
}
45+
return this.Nodes[word[0]-'a'].Search(word[1:])
46+
}
47+
48+
func (this *Trie) StartsWith(prefix string) bool {
49+
if len(prefix) == 0 {
50+
return true
51+
}
52+
if this.Nodes[prefix[0]-'a'] == nil {
53+
return false
54+
}
55+
return this.Nodes[prefix[0]-'a'].StartsWith(prefix[1:])
56+
}
57+
58+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Complexity
2+
- Time complexity: $$O(n)$$
3+
- 링크드 리스트의 길이 n에 대하여, 최악의 경우 모든 원소를 순회하므로 비용 `n`이 발생한다.
4+
5+
- Space complexity: $$O(n)$$
6+
- 링크드 리스트의 길이 n에 대하여, 최악의 경우 모든 원소를 순회하며 콜 스택에서 비용 `n`이 발생한다.
7+
# Code
8+
```go
9+
func sizeOf(root *TreeNode) int {
10+
if root == nil {
11+
return 0
12+
}
13+
14+
return sizeOf(root.Left) + sizeOf(root.Right) + 1
15+
}
16+
17+
func kthSmallest(root *TreeNode, k int) int {
18+
leftSize := sizeOf(root.Left)
19+
if k < leftSize+1 {
20+
return kthSmallest(root.Left, k)
21+
} else if k == leftSize+1 {
22+
return root.Val
23+
} else {
24+
return kthSmallest(root.Right, k-leftSize-1)
25+
}
26+
}
27+
28+
```

word-search/invidam.go.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Complexity
2+
- Time complexity: $O(R*C)$
3+
- `board`의 행과 열이 크기인 R과 C에 대하여, 이들을 모두 순회할 수 있으므로 R*C가 소모된다.
4+
5+
- Space complexity: $O(R*C)$
6+
- `board`의 행과 열이 크기인 R과 C에 대하여, 방문 여부를 기록하는 2차원 배열(`visited`)과 콜스택의 최대 크기 모두 R*C이다.
7+
# Code
8+
```go
9+
var offsets = [][]int{
10+
{1, 0},
11+
{-1, 0},
12+
{0, 1},
13+
{0, -1},
14+
}
15+
16+
func makeVisited(rows, cols int) [][]bool {
17+
visited := make([][]bool, rows)
18+
for i := range visited {
19+
visited[i] = make([]bool, cols)
20+
}
21+
return visited
22+
}
23+
24+
func existFrom(board [][]byte, i int, j int, word string, visited [][]bool) bool {
25+
if len(word) == 0 {
26+
return true
27+
} else if i < 0 || i >= len(board) || j < 0 || j >= len(board[0]) || board[i][j] != word[0] || visited[i][j] {
28+
return false
29+
}
30+
visited[i][j] = true
31+
defer func() { visited[i][j] = false }()
32+
33+
for _, offset := range offsets {
34+
if existFrom(board, i+offset[0], j+offset[1], word[1:], visited) {
35+
return true
36+
}
37+
}
38+
return false
39+
}
40+
41+
func exist(board [][]byte, word string) bool {
42+
for i, row := range board {
43+
for j, ch := range row {
44+
if ch == word[0] && existFrom(board, i, j, word, makeVisited(len(board), len(board[0]))) {
45+
return true
46+
}
47+
}
48+
}
49+
return false
50+
}
51+
52+
```

0 commit comments

Comments
 (0)