ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 시간복잡도를 고려한 알고리즘 (3)
    Algorithm 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

     

Designed by Tistory.