Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
104 changes: 104 additions & 0 deletions clone-graph/neverlish.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package main

import "testing"

func Test_cloneGraph(t *testing.T) {
result1 := cloneGraph(&Node{
Val: 1,
Neighbors: []*Node{
{
Val: 2,
Neighbors: []*Node{
{
Val: 4,
Neighbors: []*Node{
{
Val: 3,
Neighbors: []*Node{
{
Val: 1,
},
{
Val: 4,
},
},
},
{
Val: 1,
Neighbors: []*Node{
{
Val: 3,
},
{
Val: 2,
},
},
},
},
},
{
Val: 1,
Neighbors: []*Node{
{
Val: 4,
},
{
Val: 2,
},
},
},
},
},
{
Val: 3,
Neighbors: []*Node{
{
Val: 4,
},
{
Val: 1,
},
},
},
},
})

if result1.Val != 1 {
t.Fatal(result1.Val)
}
}

type Node struct {
Val int
Neighbors []*Node
}

func dfs(node *Node, visited map[*Node]*Node) *Node {
if node == nil {
return nil
}

if _, ok := visited[node]; ok {
return visited[node]
}

cloneNode := &Node{Val: node.Val}

visited[node] = cloneNode

for _, neighbor := range node.Neighbors {
cloneNode.Neighbors = append(cloneNode.Neighbors, dfs(neighbor, visited))
}

return cloneNode
}

func cloneGraph(node *Node) *Node {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

깔끔한 코드라서 이해하기 좋네요!
이 문제에만 복잡도 분석이 빠져있는데, 의도 하셨을수도 있지만 혹시 실수이실까 해서 코멘트 남깁니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거는 제가 빼먹었네요 ㅎㅎ 감사합니다

if node == nil {
return nil
}

visited := make(map[*Node]*Node)

return dfs(node, visited)
}
46 changes: 46 additions & 0 deletions longest-common-subsequence/neverlish.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 시간복잡도: O(n^2)
// 공간복잡도: O(n^2)

package main

import "testing"

func Test_longestCommonSubsequence(t *testing.T) {
result1 := longestCommonSubsequence("abcde", "ace")

if result1 != 3 {
t.Fatal(result1)
}

result2 := longestCommonSubsequence("abc", "abc")

if result2 != 3 {
t.Fatal(result2)
}

result3 := longestCommonSubsequence("abc", "def")

if result3 != 0 {
t.Fatal(result3)
}
}

func longestCommonSubsequence(text1 string, text2 string) int {
commonSubsequence := make([][]int, len(text1)+1)

for i := 0; i < len(text1)+1; i++ {
commonSubsequence[i] = make([]int, len(text2)+1)
}

for i := 1; i < len(text1)+1; i++ {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 이하에서는 commonSubsequence[i-1] 미만의 변수는 사실상 더이상 사용되지 않는것 같아요. 이를 덜어내는 방식으로 공간복잡도 최적화가 가능하지 않을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생각해보니 이전, 현재 포인터만 저장하면 되겠네요!

for j := 1; j < len(text2)+1; j++ {
if text1[i-1] == text2[j-1] {
commonSubsequence[i][j] = commonSubsequence[i-1][j-1] + 1
} else {
commonSubsequence[i][j] = max(commonSubsequence[i-1][j], commonSubsequence[i][j-1])
}
}
}

return commonSubsequence[len(text1)][len(text2)]
}
51 changes: 51 additions & 0 deletions longest-repeating-character-replacement/neverlish.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// 시간복잡도: O(n)
// 공간복잡도: O(1)

package main

import "testing"

func Test_characterReplacement(t *testing.T) {
result1 := characterReplacement("ABAB", 2)
if result1 != 4 {
t.Fatal(result1)
}

result2 := characterReplacement("AABABBA", 1)
if result2 != 4 {
t.Fatal(result2)
}
}

func maxValue(m map[byte]int) int {
max := 0
for _, v := range m {
if v > max {
max = v
}
}
return max
}

func characterReplacement(s string, k int) int {
max_length := 0
counter := make(map[byte]int)

window_start := 0
window_end := 0

for window_end < len(s) {
counter[s[window_end]]++

for window_end-window_start+1-maxValue(counter) > k {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxValue(counter)에서 추가적인 시간복잡도로 O(k)가 발생할 것으로 보여요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요건 코드를 다시 훑어보았는데,
문제 제약사항 중 0 <= k <= s.length 가 있어서,

O(k)를 더한다고 해도 O(2n) 보다 커지지 않을거 같아서, O표기법에 따라서 그대로 O(n) 으로 둘까 하는데 어떨까요

counter[s[window_start]]--
window_start++
}

max_length = max(max_length, window_end-window_start+1)

window_end++
}

return max_length
}
34 changes: 34 additions & 0 deletions number-of-1-bits/neverlish.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 시간복잡도: O(1)
// 공간복잡도: O(1)

package main

import "testing"

func Test_hammingWeight(t *testing.T) {
result1 := hammingWeight(11)
if result1 != 3 {
t.Fatal(result1)
}

result2 := hammingWeight(128)

if result2 != 1 {
t.Fatal(result2)
}

result3 := hammingWeight(2147483645)

if result3 != 30 {
t.Fatal(result3)
}
}

func hammingWeight(n int) int {
result := 0
for n > 0 {
result += n & 1
n >>= 1
}
return result
}
27 changes: 27 additions & 0 deletions sum-of-two-integers/neverlish.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 시간복잡도: O(1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

carry 가 발생하는 경우에는 O(log n)의 복잡도가 필요할 것으로 보여요
ex) 0b1111 + 0b1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요건 몰랐던 사실인데 덕분에 배워갑니다 😄

// 공간복잡도: O(1)

package main

import "testing"

func Test_getSum(t *testing.T) {
result1 := getSum(1, 2)
if result1 != 3 {
t.Fatal(result1)
}

result2 := getSum(2, 3)
if result2 != 5 {
t.Fatal(result2)
}
}

func getSum(a int, b int) int {
for b != 0 {
carry := a & b
a = a ^ b
b = carry << 1
}
return a
}
Loading