Skip to content

Commit

Permalink
feat(invidam): week 2 update.
Browse files Browse the repository at this point in the history
  • Loading branch information
Invidam committed May 9, 2024
1 parent 71d9c80 commit 149effb
Show file tree
Hide file tree
Showing 5 changed files with 436 additions and 0 deletions.
91 changes: 91 additions & 0 deletions invert-binary-tree/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
Use DFS, referencing the property of a tree (i.e. child node is the root node of a subtree.)
# Approach
<!-- Describe your approach to solving the problem. -->
1. Visit the root node.
2. If visited node is `nil`, return `nil`
3. Swap left and right nodes.
4. Visit Swapped left and right nodes.
5. Repeat Step 2 ~ 4.
# Complexity
- Time complexity: $$O(n)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: $$O(n)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```
func invertTree(root *TreeNode) *TreeNode {
if root == nil {
return nil
}
root.Left, root.Right = invertTree(root.Right), invertTree(root.Left)
return root
}
```
- - -
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
Visit, But Use BFS. (`for loop`)
# Approach
<!-- Describe your approach to solving the problem. -->
1. Create Queue and push root node to it.
2. If the queue is empty, return the `root` node.
3. Otherwise, pop the top node.
4. Swap the left and right children of the removed node.
5. Push swapped children.
4. Repeat Step
# Complexity
- Time complexity: $$O(n)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: $$O(n)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```
type Queue[T any] struct {
Index int
Nodes []T
}
func NewQueue[T any]() Queue[T] {
return Queue[T]{Nodes: make([]T, 0)}
}
func (q *Queue[T]) Push(node T) {
q.Nodes = append(q.Nodes, node)
}
func (q *Queue[T]) Pop() T {
ret := q.Nodes[q.Index]
q.Index++
return ret
}
func (q *Queue[T]) IsEmpty() bool {
return q.Index == len(q.Nodes)
}
func invertTree(root *TreeNode) *TreeNode {
q := NewQueue[*TreeNode]()
q.Push(root)
for !q.IsEmpty() {
t := q.Pop()
if t == nil {
continue
}
t.Left, t.Right = t.Right, t.Left
q.Push(t.Left)
q.Push(t.Right)
}
return root
}
```

# Learned
- κ³ μ–Έμ–΄μ—μ„œ `a, b = b, a` 처럼 κ°„κ²°ν•œ 코딩이 κ°€λŠ₯ν•˜λ‹€.
- 포인터 νƒ€μž…κ³Ό 일반 νƒ€μž…μ˜ 차이 (κ³ μ–Έμ–΄μ—μ„œλŠ” 일반 νƒ€μž…μ„ λ„˜κΈΈ μ‹œ 무쑰건 λ³΅μ‚¬ν•œλ‹€.)
66 changes: 66 additions & 0 deletions linked-list-cycle/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
Makr elements as visited by setting a dirty bit.
Check Dirty bit to visited nodes.
# Approach
<!-- Describe your approach to solving the problem. -->
1. Initiate a constant value named `visited` over the input range. (In my case `-10001`.)
2. Start Visitng node. by head.
3. Check if the current node is `nil` or its value matches the visited value (Initially, the head node should not be visited value)
4. If node is valid(i.e. not `nil` and not `visited`), set the node's value as the visited value.
5. Move to the next node and repeat step 3.

# Complexity
- Time complexity: $$O(n)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->


- Space complexity: $$O(n)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
(n = list's size)
# Code
```
const visited = -10001
func hasCycle(head *ListNode) bool {
if head == nil {
return false;
}
if head.Val == visited {
return true;
}
head.Val = visited
return hasCycle(head.Next)
}
```

- - -
# Institution
Use "The tortoise and hare" Algorithom.
# Approach
<!-- Describe your approach to solving the problem. -->
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`)
2. Allow both nodes to iterate through the graph, with each node moving at its designated speed.
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.
# Complexity
- Time complexity: $$O(n)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
- Space complexity: $$O(1)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
# Code
```
func hasCycle(head *ListNode) bool {
if head == nil || head.Next == nil {
return false
}
for slow, fast := head, head.Next; fast != nil && fast.Next != nil; slow, fast = slow.Next, fast.Next.Next{
if slow == fast {
return true
}
}
return false
}
```
# Learned
- μ•½ν•œ λΆ€λΆ„μ΄μ—ˆλ˜ νˆ¬ν¬μΈν„° μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•΄ μ’€ 더 μƒκ°ν•΄λ³΄μ•˜λ‹€.
- λ°˜λ³΅λ¬Έμ„ κΉ”λ”ν•˜κ²Œ μž‘μ„±ν•˜λŠ” 법을 κ³ λ―Όν•΄λ³΄μ•˜λ‹€.
116 changes: 116 additions & 0 deletions merge-two-sorted-lists/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
λ§ν¬λ“œλ¦¬μŠ€νŠΈ --> 반볡문 or μž¬κ·€ν˜ΈμΆœμ΄ λ– μ˜¬λžλ‹€.
# Approach
<!-- Describe your approach to solving the problem. -->
- μž¬κ·€ 호좜과 반볡문 μ‚¬μ΄μ—μ„œ κ³ λ―Όν•˜μ˜€λ‹€.
- μƒˆλ‘œμš΄ λ…Έλ“œλ₯Ό λ§Œλ“€κ³ , μž‘μ€ λ…Έλ“œλ“€μ„ 이어 λΆ™μ˜€λ‹€. (V1_1, V2_1)
- μƒˆλ‘œμš΄ λ…Έλ“œμ˜ 생성 없이, κΈ°μ‘΄ λ…Έλ“œλ“€μ„ μ—°κ²°ν•˜μ—¬ ν•΄κ²°ν•  μˆ˜λ„ μžˆμ—ˆλ‹€. (V1_2, V2_2)
# Complexity
- Time complexity: $$O(N+M)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: $$O(N+M)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

(N,M은 각각 두 λ§ν¬λ“œλ¦¬μŠ€νŠΈμ˜ 길이)
# Code
```
func mergeTwoListsV1(list1 *ListNode, list2 *ListNode) *ListNode {
if list1 == nil && list2 == nil {
return nil
} else if list1 != nil {
return list1
} else if list2 != nil {
return list2
}
// assert list1, list2 is not nil
var val int
if list1.Val < list2.Val {
val = list1.Val
list1 = list1.Next
} else {
val = list2.Val
list2 = list2.Next
}
return &ListNode{Val: val, Next: mergeTwoListsV1(list1, list2)}
}
func mergeTwoListsV1_2(list1 *ListNode, list2 *ListNode) *ListNode {
if list1 == nil {
return list2
} else if list2 == nil {
return list1
}
if list1.Val < list2.Val {
list1.Next = mergeTwoListsV1_2(list1.Next, list2)
return list1
} else {
list2.Next = mergeTwoListsV1_2(list1, list2.Next)
return list2
}
}
func mergeTwoListsV2_1(list1 *ListNode, list2 *ListNode) *ListNode {
var head = &ListNode{}
curr := head
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
curr.Next = list1
list1 = list1.Next
} else {
curr.Next = list2
list2 = list2.Next
}
curr = curr.Next
}
if list1 != nil {
curr.Next = list1
} else if list2 != nil {
curr.Next = list2
}
return head.Next
}
func mergeTwoListsV2_2(list1 *ListNode, list2 *ListNode) *ListNode {
if list1 == nil {
return list2
} else if list2 == nil {
return list1
}
head := list1
if list1.Val > list2.Val {
head = list2
list2 = list2.Next
} else {
list1 = list1.Next
}
curr := head
for list1 != nil && list2 != nil {
if list1.Val < list2.Val {
curr.Next = list1
list1 = list1.Next
} else {
curr.Next = list2
list2 = list2.Next
}
curr = curr.Next
}
if list1 != nil {
curr.Next = list1
} else if list2 != nil {
curr.Next = list2
}
return head
}
```
61 changes: 61 additions & 0 deletions reverse-linked-list/invidam.go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Intuition
두 λ³€μˆ˜κ°„μ˜ Swap이 λ– μ˜¬λžλ‹€.

# Approach
<!-- Describe your approach to solving the problem. -->
- λ§ν¬λ“œ 리슀트의 "μ–Έμ œλ‚˜ μžμ‹ μ˜ κ°’κ³Ό λ‹€μŒ λ…Έλ“œμ˜ μ£Όμ†Œλ₯Ό μœ μ§€ν•œλ‹€"λŠ” νŠΉμ„±μ΄ μž¬κ·€ ν•¨μˆ˜λ₯Ό μœ μš©ν•˜κ²Œ μ“Έ 수 μžˆλ‹€κ³  νŒλ‹¨ν–ˆλ‹€.
# Complexity
- Time complexity: $$O(n)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: $$O(n)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

(N은 λ§ν¬λ“œλ¦¬μŠ€νŠΈμ˜ 길이)
*/

# Code
- V1은 μž¬κ·€ν˜ΈμΆœ, V2λŠ” 반볡문 ν™œμš©μ„ ν•œ κ²½μš°μ΄λ‹€.
- V3은 V1을 κ°œμ„ ν•˜μ—¬, ν•˜λ‚˜μ˜ ν•¨μˆ˜λ§ŒμœΌλ‘œ κ°„κ²°ν•˜κ²Œ ν•΄κ²°ν–ˆλ‹€.
```
func reverseListV3(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
newHead := reverseList(head.Next)
head.Next.Next = head
head.Next = nil
return newHead
}
func reverseListV2(head *ListNode) *ListNode {
var prev *ListNode
curr := head
for curr != nil {
next := curr.Next
curr.Next = prev
prev = curr
curr = next
}
return prev
}
func reverseNodeAllV1(head *ListNode, prev *ListNode) *ListNode {
if head == nil {
return prev
}
next := head.Next
head.Next = prev
return reverseNodeAllV1(next, head)
}
func reverseListV1(head *ListNode) *ListNode {
return reverseNodeAllV1(head, nil)
}
```

# Remind
μž¬κ·€ ν•¨μˆ˜μ˜ νŠΉμ„±(자기 μžμ‹ μ„ ν˜ΈμΆœν•œ 이후 μ΄μ „μ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ‹€λŠ” 점)을 ν™œμš©ν•΄ κ°„κ²°ν•œ 코딩이 κ°€λŠ₯ν•˜λ‹€.
Loading

0 comments on commit 149effb

Please sign in to comment.