Longest Substring Without Repeating Characters
첫번째 풀이 O(n2)
처음 접근
처음 접근법은 abcabcbb, 이중 반복문
을 통해서 첫번째 문자열과 일치하는지를 확인하고, 일치하면, 거기서 break
를 걸어서 문자열 대치를 진행했다. 문제점은 첫번째 문자열만 일치한다는 점이였고, 2, 3 ... 이어지는 문자열이 존재하는지는 확인하지 못했다.
따라서 수정한 접근, Hash Map을 활용한 Brute Force - O(n2)
그래서 HashMap
을 따로 생성하여, 반복적으로 확인하는 문자열마다 HashMap
에 존재여부를 판단하여, 진행한다.
a := "abcabcbb"
var ans, tmp int = 0, 0
var hMap = make(map[rune]int)
for j, i := range a {
hMap[i] = 1
tmp = 1
for _, k := range a[j+1:] {
_, exists := hMap[k]
if !exists {
tmp++
hMap[k] = 1
} else {
break
}
}
if ans < tmp {
ans = tmp
}
}
return ans
Details
Runtime: 334 ms, faster than 14.81% of Go online submissions for Longest Substring Without Repeating Characters.
Memory Usage: 10.2 MB, less than 5.65% of Go online submissions for Longest Substring Without Repeating Characters.
LeetCode 풀이법 투 포인터 이용 알고리즘 O(n)
투포인터 알고리즘
은 두 개의 포인터, 즉 left, right 나누어서 윈도우 내에 있는 데이터를 이용해서 left, right 포인터를 바꿔가며, 풀이하는 알고리즘을 말합니다. 이렇게 하면, 이중 반복문을 쓰지 않는 결과가 나옵니다.
a := "abcabcbb"
var left, right, res int
ch := make(map[byte]int)
for right < len(a) {
// 존재하는지 확인!
index, exist := ch[a[right]]
fmt.Println(index, exist)
// 존재하면, 존재하는 index 인덱스에서 right 다시 증명 시작
// left가 존재하는 다음 자리에서 다시 증명을 시작하는 이유는
// 이미 right까지 중복한 숫자가 없다는 것을 증명했기 떄문
if exist && index >= left {
left = index + 1
}
if res < right-left+1 {
res = right - left + 1
}
ch[a[right]] = right
right += 1
}
투포인터를 이용해서, 알고리즘을 수정하면 O(n)이라는 결과값이 나옵니다.
Details
Runtime: 8 ms, faster than 74.88% of Go online submissions for Longest Substring Without Repeating Characters.
Memory Usage: 2.9 MB, less than 76.09% of Go online submissions for Longest Substring Without Repeating Characters.
'알고리즘 > 문제' 카테고리의 다른 글
차이를 최대로 - 10819 (C++, DFS) (0) | 2024.01.28 |
---|---|
ATM - 11399 (C++) (0) | 2024.01.18 |
LeetCode - Two Sum (Golang) (0) | 2022.01.14 |
백준 9012 괄호 - C++ 풀이 공유 (0) | 2021.02.24 |
BOJ 10163 색종이 - C++ 풀이공유 (0) | 2021.02.16 |