Kadence의 알고리즘: 최대 합 연속 하위 배열

가장 큰 합계 연속 하위 배열은 무엇입니까?

하위 배열은 배열의 연속적인 부분입니다. 배열의 단일 요소일 수도 있고 배열의 일부일 수도 있습니다. 합이 가장 큰 연속 부분배열은 합이 최대인 부분배열을 의미한다.

예를 들어 배열은 {-10, 5, 1, 6, -9, 2, -7, 3, -5}입니다. 해당 하위 배열은 {-10,5,1,6} 또는 {5,1,6} 또는 {2,7,3, -5} 등일 수 있습니다. 그러나 {5,1,6,3}은 하위 배열은 시퀀스를 유지하지 않기 때문입니다.

최대 합계 연속 하위 배열

모든 부분 배열 중에서 다음 강조된 부분 배열(5,1,6)이 최대 합산 값을 갖는다는 것을 알 수 있습니다.

최대 합계 연속 하위 배열

하위 배열 {5,1,6} = 11의 합은 위 배열의 하위 배열의 가능한 모든 조합에서 최대 합입니다. 따라서 위 배열의 경우 최대 하위 배열은 {5,1,6}입니다.

Kadence의 알고리즘: 최대 합 연속 하위 배열

가장 큰 합계 연속 부분배열을 해결하는 간단한 접근 방식

이 문제를 해결하는 간단한 방법은 두 개의 루프를 사용하여 모든 하위 배열을 찾고 합계를 계산한 다음 최대값을 찾는 것입니다.

다음은 가장 큰 연속 하위 배열 합계를 찾는 간단한 접근 방식에 대한 순서도입니다. 가능한 모든 하위 배열을 살펴보게 되므로 이는 무차별 대입 접근 방식입니다.

가장 큰 합계를 구하는 간단한 접근 방식

이를 수행하는 간단한 단계는 다음과 같습니다.

단계 1) 최소 정수 값으로 max_sum을 초기화하고 변수 "begin" 및 "end"에 XNUMX을 할당합니다.

단계 2) i와 j를 배열의 인덱스로 설정합니다. 여기서 "j"는 "i"보다 큽니다. 하위 배열의 시작 인덱스를 나타내고, "j"는 하위 배열의 끝 인덱스를 나타냅니다.

단계 3) "Current_sum"은 하위 배열의 합계를 보유합니다. 현재 합계를 계산한 후 current_sum이 max_sum보다 큰지 확인합니다.

단계 4) current_sum이 더 크면 max_sum을 현재 합계로 바꿉니다.

단계 5) "j"가 배열의 끝에 도달했는지 확인하십시오. "j"가 배열의 끝에 도달하면 "i"를 증가시키고 current_sum 값을 0으로 변경합니다.

단계 6) "i"가 배열의 끝에 도달할 때까지 이 모든 단계를 수행하십시오.

단계 7) 이 두 루프가 끝나면 max_sum은 가장 큰 하위 배열 합계를 보유합니다.

간단한 접근 방식을 위한 의사 코드

  function maximumSubarraySum():
    input: array
  for all possible subArray from array:
    calculate sum of each sub array
    store the maximum subArray
  return the maximum sum

C++ 간단한 접근 방식 구현

#include <stdio.h>
#include <iostream>
using namespace std;
void maximumSubarraySum(int array[], int n) {
  int max_sum = -1e9;
  int begin = 0;
  int end = 0;
  for (int i = 0; i < n; i++) {
    int current_sum = 0;
    for (int j = i; j < n; j++) {
      current_sum += array[j];
      if (max_sum < current_sum) {
        max_sum = current_sum;
        begin = i;
        end = j;
      }
    }
  }
  cout << "largest sum is " << max_sum << endl;
  cout << "largest sum contiguous subarray: ";
  for (int i = begin; i <= end; i++) {
    cout << array[i] << "\t";
  }
}
int main() {
  int array[] = {-10, 5, 1, 6, -9, 2, -7, 3, -5};
  maximumSubarraySum(array, sizeof(array) / sizeof(array[0]));
}

출력:

largest sum is 12
largest sum contiguous subarray: 5      1       6

Python 간단한 접근방식 구현

def maximumSubarraySum(numbers):
max_sum,begin,end = -1e9, 0 , 0
  for i in range(len(numbers)):
    current_sum=0
  for j in range(i,len(numbers)):
    current_sum+=numbers[j]
  if max_sum<current_sum:
    max_sum=current_sum
  begin,end=i,j
    print("largest sum is ",max_sum)
    print("largest sum contiguous subarray: ",end="")
  for i in range(begin,end+1):
    print(numbers[i],end='\t')
    numbers = [-10,5,1,6,-9,2,-7,3,-5]
    maximumSubarraySum(numbers)

출력:

largest sum is 12
largest sum contiguous subarray: 5      1       6

가장 큰 합계 연속 하위 배열을 찾는 Kadane의 알고리즘

Kadane의 알고리즘은 일종의 "동적 프로그래밍" 방법입니다. 여기서는 두 개의 루프 대신 하나의 루프를 사용합니다. Kadane 알고리즘의 일반적인 구현은 양수 배열에만 작동합니다.

가장 큰 합계 연속 하위 배열을 찾으려면 두 개의 변수만 필요합니다. Kadane 알고리즘의 순서도는 다음과 같습니다.

가장 큰 합계를 찾는 Kadane의 알고리즘

Kadane 알고리즘의 단계는 다음과 같습니다.

단계 1) current_sum과 max_sum이라는 두 개의 변수를 만듭니다.

“Current_sum”은 특정 배열 인덱스로 끝나는 최대 합계 값을 유지하고, “max_sum”은 지금까지의 최대 합계 값을 저장합니다.

단계 2) 각 배열 요소에 대해 current_sum과 함께 값을 추가합니다. 그런 다음 아래 두 가지 조건을 확인하겠습니다.

  • current_sum이 현재 요소보다 작으면 current_sum 값이 현재 요소가 됩니다.
  • max_sum이 current_sum보다 작으면 max_sum은 current_sum이 됩니다.

단계 3) 전체 배열에 대해 이전 단계를 수행하면 "max_sum" 변수에서 가장 큰 합계의 연속 하위 배열을 갖게 됩니다.

Kadane 알고리즘의 예

우리는 작은 크기의 배열을 사용하여 Kadanes의 알고리즘을 시연하고 가장 큰 합계 연속 부분 배열을 찾는 모든 단계에 대해 논의할 것입니다.

주어진 배열이 다음과 같다고 가정해 보겠습니다.

Kadane 알고리즘의 예

Kadane 알고리즘의 단계는 다음과 같습니다.

단계 1) current_sum과 max_sum이라는 두 개의 변수를 만듭니다. max_sum에 INT_MIN을 할당하고 current_sum에 XNUMX을 할당합니다. (여기서 INT_MIN은 최소 정수를 의미합니다.)

단계 2) 인덱스 0에서 값은 4입니다. 따라서 current_sum = 0 + 4 또는 4입니다. 여기서 current_sum은 max_sum보다 크며 max_sum은 4가 됩니다.

Kadane 알고리즘의 예

단계 3) 인덱스 1에서 값은 -2입니다. 따라서 current_sum = 4 + (-2) 또는 2입니다.

이번에는 current_sum이 max_sum보다 작습니다. 결과적으로 max_sum 값은 업데이트되지 않습니다.

Kadane 알고리즘의 예

단계 4) 다음 값은 1입니다. 이것을 current_sum에 추가하면 current_sum은 3이 됩니다. 그래도 max_sum은 current_sum보다 큽니다. 따라서 max_sum은 업데이트되지 않습니다.

Kadane 알고리즘의 예

단계 5) 인덱스 3에서 값은 3입니다. current_sum을 6씩 증가시켜 값을 업데이트하겠습니다. 따라서 current_sum은 XNUMX이 됩니다.

Kadane 알고리즘의 예

이 경우 max_sum은 current_sum보다 작습니다. 따라서 max_sum은 current_sum 값으로 업데이트됩니다.

단계 6) 배열의 마지막 요소에는 -1이 있습니다. 이것을 current_sum과 함께 추가하면 current_sum은 5가 되며 이는 max_sum보다 작습니다. 따라서 max_sum은 6으로 유지됩니다.

Kadane 알고리즘의 예

배열의 끝에 도달하면 알고리즘이 여기서 끝납니다. 이제 "max_sum"에는 최대 합계 하위 배열이 포함됩니다. 5입니다. 하위 배열은 {4,-2,1,3}입니다.

Kadane 알고리즘의 의사 코드

function KadaneAlgorithm():
    input: array
    maximum_sum, current_sum = 0
    for each elements in array:
        add the element with current_sum
        if current_sum is greater than the maximum_sum
            then maximum_sum = current_sum
        if current_sum is less than the element
            then current_sum = element
    return the value of maximum_sum

C++Kadane 알고리즘 구현

#include < iostream >
using namespace std;
void kadane(int array[], int n) {
  int current_sum = 0;
  int max_sum = -1e9;
  // -1e9 means -10000000
  for (int i = 0; i < n; i++) {
    current_sum += array[i];
    if (max_sum < current_sum) {
      max_sum = current_sum;
    }
    if (current_sum < array[i]) {
      current_sum = array[i];
    }
  }
  cout << "largest sum is " << max_sum << endl;
}
int main() {
  int array[] = {-10, 5, 1, 6, -9, 2, -7, 3, -5};
  kadane(array, sizeof(array) / sizeof(array[0]));
}

출력:

largest sum is 12

Python Kadane 알고리즘 구현

def kadane(numbers):
  current_sum = 0
  max_sum = -1e9
for i in range(len(numbers)):
  current_sum += numbers[i]
if max_sum < current_sum:
  max_sum = current_sum
if current_sum<numbers[i]:
  current_sum = numbers[i]
  print("largest sum is ",max_sum)
  kadane([-10,5,1,6,-9,2,-7,3,-5])

출력:

largest sum is 12

가장 큰 합 연속 부분 배열에 대한 복잡성 분석

간단한 접근 방식은 두 개의 루프를 사용합니다. 이 방법은 가능한 모든 하위 배열 합계를 계산하여 가장 큰 것을 찾습니다. 그것은 무차별적인 접근 방식입니다. 각 루프는 해당 루프가 끝날 때까지 실행됩니다. 정렬.

배열의 총 개수가 다음과 같은 경우 N 그런 다음 두 개의 루프를 사용하여 N을 거치게 됩니다.2 요소. 결과적으로 가장 큰 합 연속 부분 배열을 찾는 간단한 접근 방식의 시간 복잡도는 다음과 같습니다. O(N2). 여기서 “O”는 복잡도 함수를 의미합니다.

반면, Kadane의 알고리즘은 최대 연속 합계 하위 배열을 찾는 동적 프로그래밍 방법입니다. 예제나 코드를 따라가면 루프를 하나만 사용하고 있음을 알 수 있습니다.

결과적으로 입력 배열의 크기가 N, 그러면 카다네 알고리즘의 시간 복잡도는 O(N)이 됩니다. 이는 간단한 접근 방식보다 빠릅니다. 예를 들어, 100개의 요소를 포함하는 배열입니다. 간단한 접근 방식은 100*100 또는 10,000 CPU 시간이 걸립니다. 하지만 카다네 알고리즘은 100 CPU 시간만 걸립니다.