시간복잡도를 고려한 알고리즘 (3)
아래 문제는 코딜리티에서 제공하는 TapeEquilibrium의 문제입니다🧑🏻💻
문제 제시
A non-empty array A consisting of N integers is given. Array A represents numbers on a tape.
Any integer P, such that 0 < P < N, splits this tape into two non-empty parts: A[0], A[1], ..., A[P − 1] and A[P], A[P + 1], ..., A[N − 1].
The difference between the two parts is the value of: |(A[0] + A[1] + ... + A[P − 1]) − (A[P] + A[P + 1] + ... + A[N − 1])|
In other words, it is the absolute difference between the sum of the first part and the sum of the second part.
For example, consider array A such that:
A[0] = 3 A[1] = 1 A[2] = 2 A[3] = 4 A[4] = 3
We can split this tape in four places:
- P = 1, difference = |3 − 10| = 7
- P = 2, difference = |4 − 9| = 5
- P = 3, difference = |6 − 7| = 1
- P = 4, difference = |10 − 3| = 7
Write a function:
class Solution { public int solution(int[] A); }
that, given a non-empty array A of N integers, returns the minimal difference that can be achieved.
For example, given:
A[0] = 3 A[1] = 1 A[2] = 2 A[3] = 4 A[4] = 3
the function should return 1, as explained above.
Write an efficient algorithm for the following assumptions:
- N is an integer within the range [2..100,000];
- each element of array A is an integer within the range [−1,000..1,000].
문제 해결
import Foundation
import Glibc
public func solution(_ A : inout [Int]) -> Int {
var beforeNum = 0
var afterNum = A.reduce(0){$0 + $1}
var comparativeNum = 0
for (index, item) in A.enumerated() {
beforeNum += item
afterNum -= item
let subtractNum = abs(beforeNum - afterNum)
if index == 0 {
comparativeNum = subtractNum
} else if subtractNum < comparativeNum {
comparativeNum = subtractNum
}
}
return comparativeNum
}
사용된 개념
- 고차함수(reduce)
- enumerated()
- 반복 / 조건문
문제 뒷담화
해당 문제는 시간 복잡도를 고려해볼 수 있는 또 다른 문제였다.
우선 기준점으로 왼쪽과 오른쪽을 비교하여 절대값을 구해주고 해당 절대값이 제일 낮은 차이가 나오는걸 반환해주는 문제였다.
우선 그러기위해 총합을 고차함수 reduce를 사용하여 구해주고
초기 afterNum에 해당 값을 지정해준다.
그 후 반복문을 돌며 beforeNum과 afterNum에 해당 인덱스 아이템을 더하고 빼준다.
그리고 절대값을 구한다음 첫번째 인덱스 요소였다면 해당 값을 비교값으로 바로 대입시켜준다.
그 후 부터는 작은 값을 넣기위해 비교를 통해 대입시켜준다.
마지막으로 다돌고 comparativeNum을 반환시켜주면된다.
그런데...! 100%의 케이스 성공률을 못보였다.
아래에서 보면 적은수들이 들어올때에 대한 케이스 실패로 나타나는데... 아직 방법을 찾지 못하고있다.
조건이 실패할일은 없다고 생각하는데...?!
그래도 이번 코딩은 시간복잡도를 고려하려했었는데 그 부분에서는 O(N)의 시간복잡도를 가져 성공이라고 판단한다.
[참고자료]
https://app.codility.com/c/run/trainingFJD3Z9-HYS/