Skip to content

Commit

Permalink
Merge pull request #520 from obzva/main
Browse files Browse the repository at this point in the history
[Flynn] Week 09
  • Loading branch information
obzva authored Oct 11, 2024
2 parents bfe247c + 85d05c1 commit 55e4bc8
Show file tree
Hide file tree
Showing 5 changed files with 331 additions and 0 deletions.
65 changes: 65 additions & 0 deletions find-minimum-in-rotated-sorted-array/flynn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
ํ’€์ด 1
- ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์„ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด์ง„ํƒ์ƒ‰์„ ์ด์šฉํ•˜์—ฌ ํ’€์ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
์ฃผ์–ด์ง„ ๋ฐฐ์—ด์ด A = [4,5,6,7,0,1,2] ๋ผ๊ณ  ํ•  ๋•Œ, ์ด ๋ฐฐ์—ด์€ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
A[0:3] : rotate๋˜์–ด ์•ž์œผ๋กœ ๋ฐฐ์—ด์˜ ์•ž์œผ๋กœ ์˜ฎ๊ฒจ์ง„ ๋ถ€๋ถ„
A[4:6] : rotate๋˜์–ด ๋ฐฐ์—ด์˜ ๋’ค๋กœ ๋ฐ€๋ ค๋‚œ ๋ถ€๋ถ„
์ด๊ฑธ ์กฐ๊ธˆ ๋‹ค๋ฅด๊ฒŒ ํ‘œํ˜„ํ•˜๋ฉด ์ด๋ ‡๊ฒŒ๋„ ๋ฐ”๋ผ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
f(A) = [T, T, T, T, F, F, F] (T/F: rotate๋˜์–ด ๋ฐฐ์—ด์˜ ์•ž์œผ๋กœ ์˜ฎ๊ฒจ์ง„ ๋ถ€๋ถ„์ธ๊ฐ€?)
์ด ๋•Œ, ์šฐ๋ฆฌ๊ฐ€ ์ฐพ๋Š” ๊ฐ’ (the Minimum in the rotated sorted array)๋Š” ๋‘ ๊ตฌ๊ฐ„์˜ ๊ฒฝ๊ณ„์— ์œ„์น˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค
์ฆ‰, ์ฒซ๋ฒˆ์งธ F์˜ ์œ„์น˜๋ฅผ ์ฐพ๋Š” ๋ฌธ์ œ๋กœ ๋ฐ”๊ฟ” ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹จ ๋œป์ž…๋‹ˆ๋‹ค
Big O
- N: ์ฃผ์–ด์ง„ ๋ฐฐ์—ด nums์˜ ๊ธธ์ด
- Time complexity: O(logN)
- Space complexity: O(1)
*/

func findMin(nums []int) int {
lo, hi := 0, len(nums)-1
// rotate๊ฐ€ 0๋ฒˆ ์‹คํ–‰๋œ ๊ฒฝ์šฐ, ์ด์ง„ํƒ์ƒ‰์„ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†๊ณ  ์ด์ง„ํƒ์ƒ‰์˜ ์ดˆ๊ธฐ๊ฐ’ ์„ค์ •์ด ๊นŒ๋‹ค๋กœ์›Œ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜์Œ์— ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค
// ์•ž์„œ hi์˜ ์ดˆ๊ธฐ๊ฐ’์„ ์„ค์ •ํ•  ๋•Œ, len(nums)๊ฐ€ ์•„๋‹Œ len(nums) - 1๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ์ด์œ ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค
if nums[lo] < nums[hi] {
return nums[lo]
}

// Go๋Š” while๋ฌธ์— ๋Œ€์‘ํ•˜๋Š” ํ‘œํ˜„์„ for๋กœ ์ด๋ ‡๊ฒŒ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค
for lo < hi {
mid := lo + (hi-lo)/2

// ๋งŒ์ผ mid๊ฐ€ ์•ž์œผ๋กœ ๋ฐ€๋ ค๋‚œ ๋ถ€๋ถ„์— ์†ํ•œ๋‹ค๋ฉด...
if nums[lo] <= nums[mid] && nums[mid] > nums[hi] {
lo = mid + 1
} else {
hi = mid
}
}

return nums[lo]
}

/*
ํ’€์ด 2
- ํ’€์ด 1์—์„œ ๋œ์–ด๋‚ผ ์ˆ˜ ์žˆ๋Š” ๋กœ์ง์„ ๋œ์–ด๋‚ธ ์ข€ ๋” ๊น”๋”ํ•œ ์ด์ง„ํƒ์ƒ‰ ํ’€์ด์ž…๋‹ˆ๋‹ค
Big O
- ํ’€์ด 1๊ณผ ๋™์ผ
*/

func findMin(nums []int) int {
lo, hi := 0, len(nums)

for lo < hi {
mid := lo+(hi-lo)/2

if nums[mid] > nums[len(nums)-1] {
lo = mid + 1
} else {
hi = mid
}
}

return nums[lo]
}
51 changes: 51 additions & 0 deletions linked-list-cycle/flynn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* ํ’€์ด
* - Floyd's Tortoise and Hare Algorithm์„ ์ด์šฉํ•œ ํ’€์ด์ž…๋‹ˆ๋‹ค.
* ์ฐธ๊ณ : https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare
*
* Big O
* - N: ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜
* - L: ๋ฃจํ”„ ๊ตฌ๊ฐ„์— ์†ํ•˜๋Š” ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜
*
* Time Complexity: O(N)
* - ๋ฃจํ”„๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ:
* - fast ํฌ์ธํ„ฐ๊ฐ€ ๋งํฌ๋“œ๋ฆฌ์ŠคํŠธ์˜ ๋๊นŒ์ง€ ์ด๋™ํ•˜๋ฉด ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
* - ์ด ๋•Œ fast ํฌ์ธํ„ฐ์˜ ํƒ์ƒ‰ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
* O(N / 2) = O(N)
* - ๋ฃจํ”„๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ:
* - slow ํฌ์ธํ„ฐ์™€ fast ํฌ์ธํ„ฐ๊ฐ€ ๋ฃจํ”„ ์•ˆ์—์„œ ๋งŒ๋‚˜๋ฉด ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
* - ์ด ๋•Œ slow ํฌ์ธํ„ฐ์˜ ํƒ์ƒ‰ ์‹œ๊ฐ„ ๋ณต์žก๋„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
* O((N - L) + L * c) (c๋Š” slow๊ฐ€ fast๋ฅผ ๋งŒ๋‚  ๋•Œ๊นŒ์ง€ ๋ฃจํ”„๋ฅผ ๋ฐ˜๋ณตํ•œ ํšŸ์ˆ˜)
* = O(r + (N - r) * c) (L์€ 0 <= r <= N์ธ r์— ๋Œ€ํ•ด N - r๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค)
* = O(N)
*
* Space Complexity: O(1)
* - ๋…ธ๋“œ์˜ ๊ฐœ์ˆ˜์— ์ƒ๊ด€์—†์ด ์ผ์ •ํ•œ ๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
*/

/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func hasCycle(head *ListNode) bool {
if head == nil {
return false
}

slow := head
fast := head

for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next

if slow == fast {
return true
}
}

return false
}
60 changes: 60 additions & 0 deletions maximum-subarray/flynn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
ํ’€์ด 1
- ์•„๋ž˜์™€ ๊ฐ™์€ memo ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์„œ ํ’€์ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (์ฐธ๊ณ : Kadane's Algorithm)
memo[i] = nums[:i] ์ค‘์—์„œ nums[i]๋ฅผ ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•˜๋Š” ๋ถ€๋ถ„ ๋ฐฐ์—ด์˜ ์ตœ๋Œ€ ํ•ฉ
Big O
- N: ์ฃผ์–ด์ง„ ๋ฐฐ์—ด nums์˜ ๊ธธ์ด
- Time complexity: O(N)
- Space complexity: O(N)
*/

func maxSubArray(nums []int) int {
n := len(nums)

memo := make([]int, n)
copy(memo, nums)

maxSum := nums[0]

for i := 1; i < n; i++ {
if memo[i-1] > 0 {
memo[i] += memo[i-1]
}

if maxSum < memo[i] {
maxSum = memo[i]
}
}

return maxSum
}

/*
ํ’€์ด 2
- ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์ „๊ฐœ ๊ณผ์ •์„ ๋ณด๋ฉด O(N)์˜ ๊ณต๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ–๋Š” memo๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
- memo ๋ฐฐ์—ด ๋Œ€์‹  ํ˜„์žฌ ๊ณ„์‚ฐ ์ค‘์ธ ๋ถ€๋ถ„ ๋ฐฐ์—ด์˜ ํ•ฉ๋งŒ ๊ณ„์† ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค
Big O
- N: ์ฃผ์–ด์ง„ ๋ฐฐ์—ด nums์˜ ๊ธธ์ด
- Time complexity: O(N)
- Space complexity: O(1)
*/

func maxSubArray(nums []int) int {
maxSum, currSum := nums[0], nums[0]

for i := 1; i < len(nums); i++ {
if currSum > 0 {
currSum += nums[i]
} else {
currSum = nums[i]
}

if maxSum < currSum {
maxSum = currSum
}
}

return maxSum
}
54 changes: 54 additions & 0 deletions minimum-window-substring/flynn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
ํ’€์ด
- ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ’€์ดํ•ฉ๋‹ˆ๋‹ค
- ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด t์˜ ๊ฐ ๋ฌธ์ž์™€ ๊ทธ ๊ฐœ์ˆ˜๋ฅผ tMap์ด๋ผ๋Š” ํ•ด์‹œ๋งต์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค
- ํ˜„์žฌ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ์— ํฌํ•จ๋œ ๋ฌธ์ž์™€ ๊ทธ ๊ฐœ์ˆ˜๋ฅผ sMap์ด๋ผ๋Š” ํ•ด์‹œ๋งต์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค
- ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ์˜ ๋๋‹จ(end)์„ ๋„“ํ˜€๋‚˜๊ฐ€๋ฉด์„œ sMap๊ณผ tMap์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค
์ด ๋•Œ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ๊ฐ€ t์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ฐพ์œผ๋ฉด ์‹œ์ž‘๋‹จ(start)์„ ์ขํ˜€์ฃผ๋ฉด์„œ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ์˜ ์ตœ์†Œํญ์„ ์ฐพ์Šต๋‹ˆ๋‹ค
์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ๊ฐ€ t์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜๋Š”์ง€๋ฅผ ํŒ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด์„œ match๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค
match๋Š” sMap[c] == tMap[c]์ธ ๋ฌธ์ž c์˜ ๊ฐœ์ˆ˜์ด๋ฉฐ, match == len(tMap) ์ฆ‰ match๊ฐ€ t์˜ ๊ณ ์œ  ๋ฌธ์ž ๊ฐœ์ˆ˜์™€ ๊ฐ™๋‹ค๋ฉด ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ๊ฐ€ t์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ๋ฅผ ์ขํ˜€์ค„ ๋•Œ์—๋„ match์˜ ๊ฐ์†Œ ์—ฌ๋ถ€๋ฅผ ์ž˜ ๊ด€์ฐฐํ•˜๋ฉฐ ์ตœ์†Œํญ์„ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค
์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ๋ฅผ ์ค„์ผ๋งŒํผ ์ค„์˜€๋‹ค๋ฉด ๋‹ค์‹œ ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ์˜ ๋๋‹จ์„ ๋„“ํ˜€๋‚˜๊ฐ€๋ฉด์„œ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค
Big O
- M: ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด s์˜ ๊ธธ์ด
- N: ์ฃผ์–ด์ง„ ๋ฌธ์ž์—ด t์˜ ๊ธธ์ด
- Time complexity: O(M + N)
- ๋ฌธ์ž์—ด s๋ฅผ ์ˆœํšŒํ•˜๋Š” ๋ฐ˜๋ณต๋ฌธ ๋‚ด์—์„œ ๊ฐ ๋ฌธ์ž๋Š” ์ตœ๋Œ€ ๋‘ ๋ฒˆ ์กฐํšŒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค (start, end) -> O(2M)
- ๋ฌธ์ž์—ด t๋กœ ํ•ด์‹œ๋งต์„ ๋งŒ๋“œ๋Š” ๋ฐ์—๋Š” O(N)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค
- O(2M + N) -> O(M + N)
- Space complexity: O(M + N)
- ๋‘ ๊ฐœ์˜ ํ•ด์‹œ๋งต์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ O(M + N)์˜ ๊ณต๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค
*/

func minWindow(s string, t string) string {
sMap, tMap := map[string]int{}, map[string]int{}
for _, r := range t {
tMap[string(r)]++
}

start, end, matched, res := 0, 0, 0, ""
for end < len(s) {
sMap[string(s[end])]++

if sMap[string(s[end])] == tMap[string(s[end])] {
matched++
}

for matched == len(tMap) {
if res == "" || len(res) > end-start+1 {
res = s[start : end+1]
}

if sMap[string(s[start])] == tMap[string(s[start])] {
matched--
}
sMap[string(s[start])]--
start++
}

end++
}

return res
}
101 changes: 101 additions & 0 deletions pacific-atlantic-water-flow/flynn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
ํ’€์ด
- BFS๋ฅผ ์ด์šฉํ•˜์—ฌ ํ’€์ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
- ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์˜ ๊ฐ€์žฅ์ž๋ฆฌ์—์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋Š” BFS๋ฅผ pacific๊ณผ atlantic์— ๋Œ€ํ•ด ๊ฐ๊ฐ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค
Big O
- M: ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์˜ ํ–‰์˜ ๊ฐœ์ˆ˜
- N: ์ฃผ์–ด์ง„ ๋ฐฐ์—ด์˜ ์—ด์˜ ๊ฐœ์ˆ˜
- Time complexity: O(MN)
- ํƒ์ƒ‰์„ ์ง„ํ–‰ํ•˜๋Š” ํšŒ์ˆ˜๋Š” ๋ฐฐ์—ด์˜ ์›์†Œ ๊ฐœ์ˆ˜์— ๋น„๋ก€ํ•˜์—ฌ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค
- Space complexity: O(MN)
- queue์˜ ์ตœ๋Œ€ ํฌ๊ธฐ๋Š” ๋ฐฐ์—ด์˜ ์›์†Œ ๊ฐœ์ˆ˜์— ๋น„๋ก€ํ•˜์—ฌ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค
- memo ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๋Š” ๋ฐฐ์—ด์˜ ์›์†Œ ๊ฐœ์ˆ˜์— ๋น„๋ก€ํ•˜์—ฌ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค
*/

type pair struct {
pacific bool
atlantic bool
}

func pacificAtlantic(heights [][]int) [][]int {
var res [][]int

m, n := len(heights), len(heights[0])

dr := []int{0, 0, 1, -1}
dc := []int{1, -1, 0, 0}

// ๋ชจ๋“  r, c์— ๋Œ€ํ•ด memo[r][c] = {pacific: false, atlantic: false}๋กœ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค
memo := make([][]pair, m)
for r := range memo {
memo[r] = make([]pair, n)
}

queue := make([][]int, 0)

// pacific์—์„œ ์‹œ์ž‘ํ•˜๋Š” BFS
for c := 0; c < n; c++ {
queue = append(queue, []int{0, c})
}
for r := 1; r < m; r++ {
queue = append(queue, []int{r, 0})
}

for len(queue) > 0 {
r, c := queue[0][0], queue[0][1]
queue = queue[1:]

memo[r][c].pacific = true

for i := 0; i < 4; i++ {
nr, nc := r+dr[i], c+dc[i]

if !(0 <= nr && nr < m && 0 <= nc && nc < n) {
continue
}

if heights[r][c] <= heights[nr][nc] && !memo[nr][nc].pacific {
queue = append(queue, []int{nr, nc})
}
}
}

// atlantic์—์„œ ์‹œ์ž‘ํ•˜๋Š” BFS
for c := 0; c < n; c++ {
queue = append(queue, []int{m - 1, c})
}
for r := 0; r < m-1; r++ {
queue = append(queue, []int{r, n - 1})
}

for len(queue) > 0 {
r, c := queue[0][0], queue[0][1]
queue = queue[1:]

memo[r][c].atlantic = true

for i := 0; i < 4; i++ {
nr, nc := r+dr[i], c+dc[i]

if !(0 <= nr && nr < m && 0 <= nc && nc < n) {
continue
}

if heights[r][c] <= heights[nr][nc] && !memo[nr][nc].atlantic {
memo[nr][nc].atlantic = true
queue = append(queue, []int{nr, nc})
}
}
}

for r, row := range memo {
for c, el := range row {
if el.pacific && el.atlantic {
res = append(res, []int{r, c})
}
}
}

return res
}

0 comments on commit 55e4bc8

Please sign in to comment.