Skip to content

Commit 626038c

Browse files
authored
Merge pull request #742 from ysle0/main
[ysle0] Week2
2 parents 109a279 + 0b703de commit 626038c

File tree

7 files changed

+171
-20
lines changed

7 files changed

+171
-20
lines changed

3sum/ysle0.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// package _sum
2+
package main
3+
4+
import (
5+
"slices"
6+
"strconv"
7+
)
8+
9+
/*
10+
* 첫 번째 수 n1
11+
* 두 번째 수 n2
12+
* 세 번째 수 n3 일때,
13+
* 2sum 문제와 동일하게 map에 모든 수를 맵핑하여
14+
* 두가지 수를 계산하여 얻을 수 있는 세가지 수가 map에 있는지를 확인하여
15+
* 중복되지 않도록 결과를 map에 저장 -> [][]int로 반환
16+
* 시간 복잡도: O(N^2)
17+
* 공간 복잡도: O(N)
18+
*/
19+
func threeSum(nums []int) [][]int {
20+
triplets := make(map[string][]int)
21+
for i, n1 := range nums[:len(nums)-2] {
22+
seen := make(map[int]int)
23+
for _, n2 := range nums[i+1:] {
24+
target := -n1 - n2
25+
if _, ok := seen[target]; ok {
26+
item := []int{n1, n2, target}
27+
slices.Sort(item)
28+
key := strconv.Itoa(item[0]) + strconv.Itoa(item[1]) + strconv.Itoa(item[2])
29+
triplets[key] = item
30+
}
31+
seen[n2] = n2
32+
}
33+
}
34+
35+
ret := make([][]int, 0)
36+
for _, t := range triplets {
37+
ret = append(ret, t)
38+
}
39+
return ret
40+
}
41+
42+
/*
43+
* 따로 맵핑하여 첫 번째 수를 고정 후, 2,3 번째 수를 순회하며 도는 첫 번째 방식과 동일하게 O(N^2) 비용은 유지
44+
* 되지만, 공간 복잡도 면에서 O(N) -> O(1)로 개선이 됨.
45+
*/
46+
func threeSum2(nums []int) [][]int {
47+
slices.Sort(nums)
48+
triplets := make(map[string][]int, 0)
49+
50+
for i := 0; i < len(nums); i++ {
51+
l, h := i+1, len(nums)-1
52+
for l < h {
53+
sum := nums[l] + nums[h] + nums[i]
54+
if sum < 0 {
55+
l++
56+
} else if sum > 0 {
57+
h--
58+
} else {
59+
k := strconv.Itoa(nums[l]) + strconv.Itoa(nums[h]) + strconv.Itoa(nums[i])
60+
nums := []int{nums[i], nums[l], nums[h]}
61+
triplets[k] = nums
62+
l++
63+
h--
64+
}
65+
}
66+
}
67+
ret := make([][]int, 0)
68+
for _, t := range triplets {
69+
ret = append(ret, t)
70+
}
71+
return ret
72+
}

climbing-stairs/ysle0.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package climbing_stairs
2+
3+
/**
4+
* 풀이: 이전 스텝을 계산하여 고정 한후 다음 조건을 확인하는 것에서 dp유형의 문제라는 생각이 들었지만
5+
* dp가 뭔지몰라 무서워 패턴은 못찾았습니다! (감정적)
6+
* 그래서 힌트 보고 피보나치 수열인 것을 파악 후 재귀하지않는 방식으로 풀었습니다.
7+
* 풀면서 피보나치도 dp의 방식으로 풀 수 있다는 걸 명확하게 알았네요. (memoization)
8+
*/
9+
func climbStairs(n int) int {
10+
return fibo(n)
11+
}
12+
13+
func fibo(n int) int {
14+
ret := []int{0, 1}
15+
for i := 2; i <= n; i++ {
16+
ret = append(ret, ret[i-1]+ret[i-2])
17+
}
18+
ret = ret[len(ret)-2:]
19+
20+
sum := 0
21+
for _, n := range ret {
22+
sum += n
23+
}
24+
return sum
25+
}

contains-duplicate/ysle0.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ package contains_duplicate
33
import "sort"
44

55
/*
6-
1. 문제
6+
1. 문제
7+
주어진 int 배열 nums에 숫자가 중복되는 경우가 한 번이라도 있으면 true, 그렇지 않으면 false 를 리턴
78
8-
주어진 int 배열 nums에 숫자가 중복되는 경우가 한 번이라도 있으면 true, 그렇지 않으면 false 를 리턴
9-
10-
2. 풀이
11-
12-
고유값만 저장하는 set(go 에서는 map)의 성질을 활용하여
13-
nums를 순회하며 set에 값이 있는지 없는지 체크하여
14-
숫자가 중복되는 경우를 체크
9+
2. 풀이
10+
고유값만 저장하는 set(go 에서는 map)의 성질을 활용하여
11+
nums를 순회하며 set에 값이 있는지 없는지 체크하여
12+
숫자가 중복되는 경우를 체크
1513
1614
3. 분석
1715
- 시간 복잡도: O(N)
@@ -37,6 +35,12 @@ func containsDuplicate(nums []int) bool {
3735
return false
3836
}
3937

38+
/*
39+
* 처음부터 오름차순으로 정렬하여 랜덤 접근의 필요성을 없앰.
40+
* 복잡도 측면에서의 개선점은 없어보임.
41+
- 시간 복잡도: O(N)
42+
- 공간 복잡도: O(N)
43+
*/
4044
func containsDuplicate_SortedApproach(nums []int) bool {
4145
// early exit for small slices
4246
if len(nums) < 2 {

longest-consecutive-sequence/ysle0.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func longestConsecutive(nums []int) int {
5757
cursor++
5858
}
5959

60-
//tmp := make([]int, 0, len(cons))
60+
// map->array
6161
tmp := make([]int, 0, len(cons))
6262
for _, v := range cons {
6363
tmp = append(tmp, v)
@@ -68,5 +68,6 @@ func longestConsecutive(nums []int) int {
6868
func(a, b int) int {
6969
return b - a
7070
})
71+
7172
return tmp[0]
7273
}

top-k-frequent-elements/ysle0.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,5 @@ func topKFrequentElements_BucketSort(nums []int, k int) []int {
114114
res = append(res, buc[i]...)
115115
}
116116

117-
return res[:k]
117+
return res
118118
}
119-
120-
//
121-
//func main() {
122-
// r1 := topKFrequent([]int{1, 1, 1, 2, 2, 3}, 2)
123-
// fmt.Println(r1)
124-
//
125-
// r2 := topKFrequent([]int{1}, 1)
126-
// fmt.Println(r2)
127-
//}

valid-anagram/ysle0.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package valid_anagram
2+
3+
/**
4+
* 풀이:
5+
* t가 s의 anagram인지 확인하는 문제!
6+
* s를 hashmap에 맵핑하고, t의 rune r을 하나씩 s[r] 로 갯수를 체크하여 풀음.
7+
* anagram이면 return true, otherwise false
8+
* true 까지 조건 3개가 있음.
9+
*
10+
* TC: O(N) -> s나 t의 길이 만큼만 돌음
11+
* SC: O(N) -> M * N에서 최고차항 정리
12+
*/
13+
func isAnagram(s string, t string) bool {
14+
ht := make(map[rune]int, len(s))
15+
for _, r := range s {
16+
ht[r]++
17+
}
18+
19+
for _, r := range t {
20+
cnt, ok := ht[r]
21+
if !ok { // 1. t에 존재하지 않는 rune -> false
22+
return false
23+
}
24+
25+
ht[r] -= 1 // t의 rune이 s에 존재하므로 갯수 1 차감
26+
if cnt-1 < 0 { // 2. s에 있는 rune보다 더 많이 가지고 있음
27+
return false
28+
}
29+
}
30+
31+
for _, v := range ht {
32+
if v > 0 { // 3. t를 순회하고 s에 남아있는게 있어도 false
33+
return false
34+
}
35+
}
36+
37+
return true
38+
}
39+
40+
func isAnagram_faster(s string, t string) bool {
41+
if len(s) != len(t) { // 둘이 길이가 다르면 당연히 실패함
42+
return false
43+
}
44+
45+
ht := make(map[byte]int, len(s))
46+
for i, _ := range s {
47+
ht[s[i]]++
48+
ht[t[i]]-- // 기존에 푼 방식에서 ok 체크 안해버림? ..
49+
}
50+
51+
for _, v := range ht {
52+
if v != 0 {
53+
return false
54+
}
55+
}
56+
return true
57+
}

valid-palindrome/ysle0.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
모든 문자열을 돌며 소문자로 변환
2525
palindrome 문자열 체크 loop
2626
앞 커서 < 뒤 커서 의 조건으로 O(n/2) ---> O(n)
27-
- 공간 복잡도: O(1)
27+
- 공간 복잡도: O(n)
2828
새로운 저장공간은 없으며 주어진 문자열 s 하나뿐
2929
*/
3030
var nonAlphanumericRegex = regexp.MustCompile(`[^a-zA-Z0-9]+`)
@@ -54,6 +54,7 @@ func isPalindrome(s string) bool {
5454
/*
5555
1. 개선점
5656
- regex 오버헤드 제거
57+
공간 복잡도를 개선: O(N) -> O(1)
5758
*/
5859
func isPalindrome_Optimized(s string) bool {
5960
front, rear := 0, len(s)-1

0 commit comments

Comments
 (0)