Skip to content

Commit e819d57

Browse files
authored
Merge pull request DaleStudy#60 from Invidam/week02-invidam
[Invidam] Week 02 Solution #GoLang
2 parents 1d29e11 + 149effb commit e819d57

File tree

5 files changed

+436
-0
lines changed

5 files changed

+436
-0
lines changed

β€Žinvert-binary-tree/invidam.go.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Intuition
2+
<!-- Describe your first thoughts on how to solve this problem. -->
3+
Use DFS, referencing the property of a tree (i.e. child node is the root node of a subtree.)
4+
# Approach
5+
<!-- Describe your approach to solving the problem. -->
6+
1. Visit the root node.
7+
2. If visited node is `nil`, return `nil`
8+
3. Swap left and right nodes.
9+
4. Visit Swapped left and right nodes.
10+
5. Repeat Step 2 ~ 4.
11+
# Complexity
12+
- Time complexity: $$O(n)$$
13+
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
14+
15+
- Space complexity: $$O(n)$$
16+
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
17+
18+
# Code
19+
```
20+
func invertTree(root *TreeNode) *TreeNode {
21+
if root == nil {
22+
return nil
23+
}
24+
root.Left, root.Right = invertTree(root.Right), invertTree(root.Left)
25+
return root
26+
}
27+
```
28+
- - -
29+
# Intuition
30+
<!-- Describe your first thoughts on how to solve this problem. -->
31+
Visit, But Use BFS. (`for loop`)
32+
# Approach
33+
<!-- Describe your approach to solving the problem. -->
34+
1. Create Queue and push root node to it.
35+
2. If the queue is empty, return the `root` node.
36+
3. Otherwise, pop the top node.
37+
4. Swap the left and right children of the removed node.
38+
5. Push swapped children.
39+
4. Repeat Step
40+
# Complexity
41+
- Time complexity: $$O(n)$$
42+
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
43+
44+
- Space complexity: $$O(n)$$
45+
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
46+
47+
# Code
48+
```
49+
type Queue[T any] struct {
50+
Index int
51+
Nodes []T
52+
}
53+
54+
func NewQueue[T any]() Queue[T] {
55+
return Queue[T]{Nodes: make([]T, 0)}
56+
}
57+
58+
func (q *Queue[T]) Push(node T) {
59+
q.Nodes = append(q.Nodes, node)
60+
}
61+
62+
func (q *Queue[T]) Pop() T {
63+
ret := q.Nodes[q.Index]
64+
q.Index++
65+
return ret
66+
}
67+
68+
func (q *Queue[T]) IsEmpty() bool {
69+
return q.Index == len(q.Nodes)
70+
}
71+
72+
func invertTree(root *TreeNode) *TreeNode {
73+
q := NewQueue[*TreeNode]()
74+
q.Push(root)
75+
for !q.IsEmpty() {
76+
t := q.Pop()
77+
if t == nil {
78+
continue
79+
}
80+
t.Left, t.Right = t.Right, t.Left
81+
82+
q.Push(t.Left)
83+
q.Push(t.Right)
84+
}
85+
return root
86+
}
87+
```
88+
89+
# Learned
90+
- κ³ μ–Έμ–΄μ—μ„œ `a, b = b, a` 처럼 κ°„κ²°ν•œ 코딩이 κ°€λŠ₯ν•˜λ‹€.
91+
- 포인터 νƒ€μž…κ³Ό 일반 νƒ€μž…μ˜ 차이 (κ³ μ–Έμ–΄μ—μ„œλŠ” 일반 νƒ€μž…μ„ λ„˜κΈΈ μ‹œ 무쑰건 λ³΅μ‚¬ν•œλ‹€.)

β€Žlinked-list-cycle/invidam.go.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Intuition
2+
<!-- Describe your first thoughts on how to solve this problem. -->
3+
Makr elements as visited by setting a dirty bit.
4+
Check Dirty bit to visited nodes.
5+
# Approach
6+
<!-- Describe your approach to solving the problem. -->
7+
1. Initiate a constant value named `visited` over the input range. (In my case `-10001`.)
8+
2. Start Visitng node. by head.
9+
3. Check if the current node is `nil` or its value matches the visited value (Initially, the head node should not be visited value)
10+
4. If node is valid(i.e. not `nil` and not `visited`), set the node's value as the visited value.
11+
5. Move to the next node and repeat step 3.
12+
13+
# Complexity
14+
- Time complexity: $$O(n)$$
15+
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
16+
17+
18+
- Space complexity: $$O(n)$$
19+
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
20+
(n = list's size)
21+
# Code
22+
```
23+
const visited = -10001
24+
func hasCycle(head *ListNode) bool {
25+
if head == nil {
26+
return false;
27+
}
28+
if head.Val == visited {
29+
return true;
30+
}
31+
head.Val = visited
32+
return hasCycle(head.Next)
33+
}
34+
```
35+
36+
- - -
37+
# Institution
38+
Use "The tortoise and hare" Algorithom.
39+
# Approach
40+
<!-- Describe your approach to solving the problem. -->
41+
1. Designate two node to move at differnt speeds. One node should move faster (referred to as `fast`), and the other should move slower (`slow`)
42+
2. Allow both nodes to iterate through the graph, with each node moving at its designated speed.
43+
3. If the `fast` node catches up to the `slow` node (i.e. both node points to the same node at same point), the the graph contains a cycle.is cycle.
44+
# Complexity
45+
- Time complexity: $$O(n)$$
46+
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
47+
- Space complexity: $$O(1)$$
48+
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
49+
# Code
50+
```
51+
func hasCycle(head *ListNode) bool {
52+
if head == nil || head.Next == nil {
53+
return false
54+
}
55+
for slow, fast := head, head.Next; fast != nil && fast.Next != nil; slow, fast = slow.Next, fast.Next.Next{
56+
if slow == fast {
57+
return true
58+
}
59+
}
60+
return false
61+
}
62+
63+
```
64+
# Learned
65+
- μ•½ν•œ λΆ€λΆ„μ΄μ—ˆλ˜ νˆ¬ν¬μΈν„° μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•΄ μ’€ 더 μƒκ°ν•΄λ³΄μ•˜λ‹€.
66+
- λ°˜λ³΅λ¬Έμ„ κΉ”λ”ν•˜κ²Œ μž‘μ„±ν•˜λŠ” 법을 κ³ λ―Όν•΄λ³΄μ•˜λ‹€.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Intuition
2+
<!-- Describe your first thoughts on how to solve this problem. -->
3+
λ§ν¬λ“œλ¦¬μŠ€νŠΈ --> 반볡문 or μž¬κ·€ν˜ΈμΆœμ΄ λ– μ˜¬λžλ‹€.
4+
# Approach
5+
<!-- Describe your approach to solving the problem. -->
6+
- μž¬κ·€ 호좜과 반볡문 μ‚¬μ΄μ—μ„œ κ³ λ―Όν•˜μ˜€λ‹€.
7+
- μƒˆλ‘œμš΄ λ…Έλ“œλ₯Ό λ§Œλ“€κ³ , μž‘μ€ λ…Έλ“œλ“€μ„ 이어 λΆ™μ˜€λ‹€. (V1_1, V2_1)
8+
- μƒˆλ‘œμš΄ λ…Έλ“œμ˜ 생성 없이, κΈ°μ‘΄ λ…Έλ“œλ“€μ„ μ—°κ²°ν•˜μ—¬ ν•΄κ²°ν•  μˆ˜λ„ μžˆμ—ˆλ‹€. (V1_2, V2_2)
9+
# Complexity
10+
- Time complexity: $$O(N+M)$$
11+
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
12+
13+
- Space complexity: $$O(N+M)$$
14+
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
15+
16+
(N,M은 각각 두 λ§ν¬λ“œλ¦¬μŠ€νŠΈμ˜ 길이)
17+
# Code
18+
```
19+
func mergeTwoListsV1(list1 *ListNode, list2 *ListNode) *ListNode {
20+
if list1 == nil && list2 == nil {
21+
return nil
22+
} else if list1 != nil {
23+
return list1
24+
} else if list2 != nil {
25+
return list2
26+
}
27+
// assert list1, list2 is not nil
28+
var val int
29+
if list1.Val < list2.Val {
30+
val = list1.Val
31+
list1 = list1.Next
32+
} else {
33+
val = list2.Val
34+
list2 = list2.Next
35+
}
36+
37+
return &ListNode{Val: val, Next: mergeTwoListsV1(list1, list2)}
38+
}
39+
40+
func mergeTwoListsV1_2(list1 *ListNode, list2 *ListNode) *ListNode {
41+
if list1 == nil {
42+
return list2
43+
} else if list2 == nil {
44+
return list1
45+
}
46+
47+
if list1.Val < list2.Val {
48+
list1.Next = mergeTwoListsV1_2(list1.Next, list2)
49+
return list1
50+
} else {
51+
list2.Next = mergeTwoListsV1_2(list1, list2.Next)
52+
return list2
53+
}
54+
}
55+
56+
func mergeTwoListsV2_1(list1 *ListNode, list2 *ListNode) *ListNode {
57+
var head = &ListNode{}
58+
curr := head
59+
60+
for list1 != nil && list2 != nil {
61+
if list1.Val < list2.Val {
62+
curr.Next = list1
63+
list1 = list1.Next
64+
} else {
65+
curr.Next = list2
66+
list2 = list2.Next
67+
}
68+
curr = curr.Next
69+
}
70+
71+
if list1 != nil {
72+
curr.Next = list1
73+
} else if list2 != nil {
74+
curr.Next = list2
75+
}
76+
77+
return head.Next
78+
}
79+
80+
func mergeTwoListsV2_2(list1 *ListNode, list2 *ListNode) *ListNode {
81+
if list1 == nil {
82+
return list2
83+
} else if list2 == nil {
84+
return list1
85+
}
86+
87+
head := list1
88+
if list1.Val > list2.Val {
89+
head = list2
90+
list2 = list2.Next
91+
} else {
92+
list1 = list1.Next
93+
}
94+
curr := head
95+
96+
for list1 != nil && list2 != nil {
97+
if list1.Val < list2.Val {
98+
curr.Next = list1
99+
list1 = list1.Next
100+
} else {
101+
curr.Next = list2
102+
list2 = list2.Next
103+
}
104+
curr = curr.Next
105+
}
106+
107+
if list1 != nil {
108+
curr.Next = list1
109+
} else if list2 != nil {
110+
curr.Next = list2
111+
}
112+
113+
return head
114+
}
115+
116+
```

β€Žreverse-linked-list/invidam.go.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Intuition
2+
두 λ³€μˆ˜κ°„μ˜ Swap이 λ– μ˜¬λžλ‹€.
3+
4+
# Approach
5+
<!-- Describe your approach to solving the problem. -->
6+
- λ§ν¬λ“œ 리슀트의 "μ–Έμ œλ‚˜ μžμ‹ μ˜ κ°’κ³Ό λ‹€μŒ λ…Έλ“œμ˜ μ£Όμ†Œλ₯Ό μœ μ§€ν•œλ‹€"λŠ” νŠΉμ„±μ΄ μž¬κ·€ ν•¨μˆ˜λ₯Ό μœ μš©ν•˜κ²Œ μ“Έ 수 μžˆλ‹€κ³  νŒλ‹¨ν–ˆλ‹€.
7+
# Complexity
8+
- Time complexity: $$O(n)$$
9+
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
10+
11+
- Space complexity: $$O(n)$$
12+
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
13+
14+
(N은 λ§ν¬λ“œλ¦¬μŠ€νŠΈμ˜ 길이)
15+
*/
16+
17+
# Code
18+
- V1은 μž¬κ·€ν˜ΈμΆœ, V2λŠ” 반볡문 ν™œμš©μ„ ν•œ κ²½μš°μ΄λ‹€.
19+
- V3은 V1을 κ°œμ„ ν•˜μ—¬, ν•˜λ‚˜μ˜ ν•¨μˆ˜λ§ŒμœΌλ‘œ κ°„κ²°ν•˜κ²Œ ν•΄κ²°ν–ˆλ‹€.
20+
```
21+
22+
func reverseListV3(head *ListNode) *ListNode {
23+
if head == nil || head.Next == nil {
24+
return head
25+
}
26+
27+
newHead := reverseList(head.Next)
28+
29+
head.Next.Next = head
30+
head.Next = nil
31+
32+
return newHead
33+
}
34+
35+
func reverseListV2(head *ListNode) *ListNode {
36+
var prev *ListNode
37+
curr := head
38+
for curr != nil {
39+
next := curr.Next
40+
curr.Next = prev
41+
prev = curr
42+
curr = next
43+
}
44+
return prev
45+
}
46+
47+
func reverseNodeAllV1(head *ListNode, prev *ListNode) *ListNode {
48+
if head == nil {
49+
return prev
50+
}
51+
next := head.Next
52+
head.Next = prev
53+
return reverseNodeAllV1(next, head)
54+
}
55+
func reverseListV1(head *ListNode) *ListNode {
56+
return reverseNodeAllV1(head, nil)
57+
}
58+
```
59+
60+
# Remind
61+
μž¬κ·€ ν•¨μˆ˜μ˜ νŠΉμ„±(자기 μžμ‹ μ„ ν˜ΈμΆœν•œ 이후 μ΄μ „μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ‹€λŠ” 점)을 ν™œμš©ν•΄ κ°„κ²°ν•œ 코딩이 κ°€λŠ₯ν•˜λ‹€.

0 commit comments

Comments
Β (0)