일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- weak var
- swift
- App Store Connect
- CoreLocation
- RunningTimer
- MKMapViewDelegate
- WeatherManager
- 서체관리자
- 영문 개인정보처리방침
- 러닝타이머
- UICollectionViewFlowLayout
- xcode로 날씨앱 만들기
- Startign Assignments
- 클로저의 캡슐화
- weatherKit
- Timer
- CLLocationManagerDelegate
- 단일 책임원칙
- UIAlertAction
- MKMapItem
- 한국어 개인정보처리방침
- Protocol
- AnyObject
- Xcode
- 러닝기록앱
- SwiftUI Boolean 값
- addannotation
- dispatchsource
- font book
- Required Reason API
Archives
- Today
- Total
VesselWheel
삼총사 (considering 시간복잡도) / 시간복잡도를 고려하니 중복값 문제 발생 본문
Coding Test Practice in Swift
삼총사 (considering 시간복잡도) / 시간복잡도를 고려하니 중복값 문제 발생
JasonYang 2024. 2. 20. 10:52문제
풀이
import Foundation
func solution(_ number:[Int]) -> Int {
var count = 0
let n = number.count
for i in 0..<n {
for j in i+1..<n {
for k in j+1..<n {
if number[i] + number[j] + number[k] == 0 {
count += 1
}
}
}
}
return count
}
해석
-> 이 풀이법은 모든 경우의 수를 탐색하기 때문에 시간복잡도 O(n^3)이다.
시간복잡도란?
더보기
시간 복잡도가 뭔가요?
💡 시간 복잡도는 꼭 최악의 경우를 기준으로 계산해야합니다.
- 정의
- 시간 복잡도는 문제를 해결하는데 걸리는 시간과 입력의 함수 관계를 가리킨다. 컴퓨터과학에서 알고리즘의 시간 복잡도는 입력을 나타내는 문자열 길이의 함수로서 작동하는 알고리즘을 취해 시간을 정량화하는 것이다. (출처: 위키피디아)
- 정의가 다소 난해하지만, 예제와 함께 직접 계산해보시면 이해가 빠릅니다.
func findMaxNum(_ array: [Int]) -> Int? {
for num in array {
for compareNum in array {
if num < compareNum {
break
}
}
else {
return num
}
}
return nil
}
let input = [3, 5, 6, 1, 2, 4]
let result = findMaxNum(input)
print("정답 = 6 / 현재 풀이 값 = ", findMaxNum([3, 5, 6, 1, 2, 4]) ?? "결과 없음")
print("정답 = 6 / 현재 풀이 값 = ", findMaxNum([6, 6, 6]) ?? "결과 없음")
print("정답 = 1888 / 현재 풀이 값 = ", findMaxNum([6, 9, 2, 7, 1888]) ?? "결과 없음")
이 함수의 시간 복잡도를 계산해볼까요?
for num in array { // array 의 길이만큼 아래 연산이 실행
for compareNum in array { // array 의 길이만큼 아래 연산이 실행
if num < compareNum { // 비교 연산 1번 실행
break
}
}
else {
return num
}
}
- 위에서 언급한 말을 다시 살펴볼게요.
- 문제를 해결하는데 걸리는 시간과 입력의 함수 관계
- 입력
- array의 원소 갯수 = N
- 실행 시간
- array의 원소 갯수 X array의 원소 갯수 X 비교 연산 1번 = N X N
- 그러면 우리는 이제 이 함수는 $N^2$ 만큼의 시간이 걸렸겠구나! 라고 말할 수 있습니다.
- 시간 복잡도는 Big-O(빅오) 표기법으로 표시하며 이 경우엔 O($N^2$)의 시간 복잡도를 가진다고 합니다.
func findMaxNum(_ array: [Int]) -> Int? {
guard let firstNum = array.first else {
return nil
}
var maxNum = firstNum
for num in array {
if num > maxNum {
maxNum = num
}
}
return maxNum
}
let input = [3, 5, 6, 1, 2, 4]
let result = findMaxNum(input)
print("정답 = 6 / 현재 풀이 값 = ", findMaxNum([3, 5, 6, 1,
- 입력
- array의 원소 갯수 = N
- 실행 시간
- max_num 대입 연산 = 1번
- max_num 대입 연산 1번 + array의 길이 X (비교 연산 1번 + 대입 연산 1번) = 1 + 2N
- 마찬가지로 이 함수는 2N + 1의 시간이 걸렸겠구나! 라고 말할 수 있습니다.
- 하지만, 빅오 표기법에서는 N의 지수부분만이 유효하게 쓰이고 나머지는 절삭합니다.
- 다시 말해서 2N + 1 → O(N)입니다.
강의자료
시간복잡도를 고려한 풀이
import Foundation
func solution(_ number: [Int]) -> Int {
var count = 0
let sortedNumbers = number.sorted()
let n = sortedNumbers.count
for i in 0..<n {
var left = i + 1
var right = n - 1
while left < right {
let sum = sortedNumbers[i] + sortedNumbers[left] + sortedNumbers[right]
if sum == 0 {
count += 1
left += 1
right -= 1
} else if sum > 0 {
right -= 1
} else {
left += 1
}
}
}
return count
}
-> 포인터 알고리즘을 사용한 풀이법을 사용하면 시간복자도를 O(n^2)으로 줄이고자 했으나,
left += 1
right -= 1
sum이 0일 때, left += 1와 right -= 1을 동시에 수행하면, 같은 합을 가지는 다른 조합을 놓칠 수 있다. 정확한 카운트를 위해 sum이 0일 때, left 또는 right 포인터만 이동시키거나, 중복된 값을 처리하는 로직을 추가해야 한다.
예를 들어, [-1, 0, 1, 1] 같은 배열이 있을 때, [-1, 0, 1]과 [-1, 0, 1]이라는 같은 합을 가지는 두 조합이 있다. 하지만 위 코드는 이 두 조합 중 하나만 카운트하게 된다.
import Foundation
func solution(_ number:[Int]) -> Int {
var count = 0
let sortedNumbers = number.sorted()
let n = sortedNumbers.count
for i in 0..<n {
var left = i + 1
var right = n - 1
while left < right {
let sum = sortedNumbers[i] + sortedNumbers[left] + sortedNumbers[right]
if sum == 0 {
count += 1
while left < right && sortedNumbers[left] == sortedNumbers[left + 1] {
left += 1
}
while left < right && sortedNumbers[right] == sortedNumbers[right - 1] {
right -= 1
}
left += 1
right -= 1
} else if sum > 0 {
right -= 1
} else {
left += 1
}
}
}
return count
}
-> sum이 0일 때, left와 right 포인터가 가리키는 값이 중복되는 경우를 처리한 코드
'Coding Test Practice in Swift' 카테고리의 다른 글
최소직사각형 (0) | 2024.02.23 |
---|---|
크기가 작은 부분문자열 (0) | 2024.02.22 |
이상한 문자 만들기 (0) | 2024.02.19 |
3진법 뒤집기 (1) | 2024.02.02 |
최대공약수와 최소공배수(feat. 유클리드 호제법) (1) | 2024.01.26 |