데이터 구조와 알고리즘 분석(1)

3846 단어

1. 최대 하위 시퀀스와 문제


입력 예: 4 - 35 - 2 6 - 2 출력: 11

1.1 이분법 귀속 구해 - 시간 복잡도: O(NlogN)

int getMax3 (int a, int b, int c)
{
    int max = a;
    if (max < b)
        max = b;
    if (max < c)
        max = c;
    return max;
}
int getMaxSum(const vector &arr, int bgn, int end)
{
    if (bgn >= end)
        return 0;
    int mid = (bgn + end) / 2;
    int leftMaxSum = getMaxSum(arr, bgn, mid);
    
    // mid + 1, 
    int rightMaxSum = getMaxSum(arr, mid + 1, end);
    
    int leftMaxBorder = 0, leftTmp = 0;
    for (int i = mid; i >= bgn; --i)
    {
        leftTmp += arr[i];
        if (leftTmp > leftMaxBorder)
            leftMaxBorder = leftTmp;
    //    if (leftTmp < 0)    // , 
    //        break;
    }
    int rightMaxBorder = 0, rightTmp = 0;
    for (int i = mid + 1; i < end; ++i)
    {
        rightTmp += arr[i];
        if (rightTmp > rightMaxBorder)
            rightMaxBorder = rightTmp;
    //    if (rightTmp < 0)
    //        break;
    }
    return getMax3(leftMaxSum, rightMaxSum, leftMaxBorder + rightMaxBorder);
}

 

1.2 한 번에 풀기 - 시간 복잡도: O(N)

int getMaxSubSum(const vector &arr, int bgn, int end)
{
    int maxSum = 0;
    int sumTmp = 0;
    for (int i = bgn; i < end; ++i)
    {
        sumTmp += arr[i];
        if (sumTmp > maxSum)
            maxSum = sumTmp;
        else if (sum < 0)
            sumTmp = 0;
    }
    return maxSum;
}

 

2. 알고리즘 시간 복잡도가 O(logN)인 일반적인 문제:


2.1 대분 찾기(binary search) - 시간 복잡도: (<=log2N)

int binSearch(const vector &arr, int bgn, int end, int target)  //end- 
{
    int ret = -1;
    while (bgn < end)
    {
        int mid = (bgn + end) / 2;
        if (target == arr[mid])
        {
            ret = mid;
            break;
        }
        else if (target > arr[mid])
            bgn = mid + 1;
        else    
            end = mid;
    }
    return ret;
}

 

2.2 두 정수 최대 공약수 구해(유클리드 알고리즘) - 시간 복잡도: (<= 2logN)

unsigned int getGCD(unsigned int m, unsigned int n)
{
    while (n > 0)
    {
        int rem = m % n;
        m = n;
        n = rem;
    }
    return m;
}

 
여기는 사실 귀속의 사상을 운용했다. m와 n의 최대 공인자는 n과rem(m%n)의 최대 공인자이다.그러면 n과rem의 최대 공인자가 m와 n의 최대 공인자라는 것만 설명하면 이 귀속을 진행할 수 있다.그래서 문제는 n과rem의 최대 공인자가 왜 m와 n의 최대 공인자입니까?
사고방식: m>n을 가정하고 mn이 있다. m와 n의 최대 공인자는 A이고 m=xA, n=yA이다.rem=m%n->m-zn(z=m/n),rem=0, n은 양자의 최대 공인자이다.rem>0,rem=xA-zyA,rem%A=0->m와 n의 최대 공인자는 n과rem의 최대 공인자로 이와 같이 추정된다

2.3멱 연산 - 시간 복잡도: (<= 2logN)

long long pow(long long x, unsigned int n)
{
    if (0 == n)
        return 1;
    if (n % 2)
        return pow( x*x, n/2 ) * x;
    else
        return pow( x*x, n/2 );
}

 
2^15를 입력으로 하면 2log(15) = 6차 곱셈 연산이 2^16을 입력으로 하면 4+1(<2log(16)=8) 곱셈 연산만 필요하고, 코드를 수정하여 출구판단(if(1==n)을 추가하여 4차례 곱셈 연산으로 만들 수도 있지만, 매번 파워에 들어갈 때마다 한 번 더 판단해야 한다
  PS: 1. 책에서 2^62를 예로 들면 모두 9차례의 곱셈 연산이 필요하지만 추론 알고리즘 과정은 개인적으로 문제가 있다고 생각한다.실제 과정은 우선 파워 입구 매개 변수 x*x의 값을 n==0까지 층층이 연산해야 한다.그리고 알고리즘이 연산이 끝날 때까지 역순으로 층층이 pow*x의 값을 계산한다.코드 중 문장 pow(x*x, n/2)는 pow(x, n/2)*pow(x, n/2)로 대체할 수 있지만 효율은 매우 낮을 것이다. 왜냐하면 대량의 중복성 작업을 진행했기 때문이다
 

좋은 웹페이지 즐겨찾기