Algorithm

시간복잡도를 고려한 알고리즘 (3)

GREEN.1229 2021. 7. 11. 13:50

아래 문제는 코딜리티에서 제공하는 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/

 

Codility

Your browser is not supported You should use a supported browser. Read more

app.codility.com