0

Kadane's Algorithm

Đề bài

You are given an integer array arr[]. You need to find the maximum sum of a subarray (containing at least one element) in the array arr[].

Note : A subarray is a continuous part of an array.

Ví dụ

Input: arr[] = [2, 3, -8, 7, -1, 2, 3]
Output: 11
Explanation: The subarray [7, -1, 2, 3] has the largest sum 11.

Các bước thực hiện

Tôi có : arr = [-2, 3, -1, 2, -1]

Cách suy nghĩ đơn giản

  • Thực hiện từ trái sang phải.
  • Tại mỗi số, hãy tự hỏi:

👉 “Có nên tiếp tục cộng nó vào đoạn hiện tại, hay bỏ đoạn cũ đi và bắt đầu một đoạn mới từ số này?”

Bắt đầu

maxSum = -2
currentSum = -2

Xét khi gặp số arr[1] = 3:

  • Nếu cộng với đoạn cũ: arr[0] + arr[1] = -2 + 3 = 1
  • Nếu bắt đầu lại từ arr[1] = 3: 3 → Cái nào lớn hơn? 3 > 1 => Chọn bắt đầu lại tính từ vị trí arr[1] = 3;

image.png

Hãy xem mảng nhỏ hơn này, bạn thử nghĩ xem việc thêm -2 vào sum có làm tổng tăng nhiều hơn khi bắt đầu lại từ 3. Rõ ràng là bắt đầu lại từ 3 rồi, khi đó ta sẽ được tổng là 3, còn nếu thêm -2 thì tổng còn 1.

maxSum = 3
currentSum = 3, 

Xét tiếp khi gặp số -1:

  • Nếu cộng tiếp: 3 + (-1) = 2
  • Nếu bắt đầu mới: -1 → Chọn 2
maxSum = 3 (vì 3 > 2)
currentSum = 2, 

Xét tiếp khi gặp số 2:

  • Nếu cộng tiếp: 2 + 2 = 4
  • Nếu bắt đầu mới: 2 → Chọn 4
maxSum = 4
currentSum = 4

Khi gặp số -1:

  • Nếu cộng tiếp: 4 + (-1) = 3
  • Nếu bắt đầu mới: -1 → Chọn 3
maxSum = 4
currentSum = 3

Kết quả cuối cùng:

maxSum = 4
Đoạn con có tổng lớn nhất là [3, -1, 2].

Code

Ở đây tôi sử dụng C++ để giải quyết.

Nếu code theo những gì tôi đã giải thích bên trên thì nó sẽ như thế này

class Solution {
  public:
    int maxSubarraySum(vector<int> &arr) {
        int length = arr.size();
        int maxSum = arr[0];
        int currentSum = arr[0];
        
        for(int i = 1; i < length; i++) {
            currentSum = currentSum + arr[i];
            
            if(currentSum > arr[i]) { // không làm gì cả
                
            }
            else if(currentSum < arr[i]) {  // bắt đầu lại từ vị trí mới
                currentSum = arr[i];
            }
            
            
            if(currentSum > maxSum) {
                maxSum = currentSum;
            }
        }
        
        return maxSum;
    }
};

Đây là code rút gọn lại

class Solution {
  public:
    int maxSubarraySum(vector<int> &arr) {
        int length = arr.size();
        int maxSum = arr[0];
        int currentSum = arr[0];
        
        for(int i = 1; i < length; i++) {
            currentSum = currentSum + arr[i];
            if(currentSum < arr[i]) {
                currentSum = arr[i];
            }
            
            if(currentSum > maxSum) {
                maxSum = currentSum;
            }
        }
        
        return maxSum;
    }
};

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí