You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

O(logn)复杂度下指定区间连续子数组最大和的实现疑问

O(logn)区间连续子数组最大和的正确解法

Hey there, let's break down your problem and find a solid solution.

First, let's talk about why your current AVL tree approach isn't working:

  • Your use of the global preIndex is a big red flag. Recursion in AVL trees doesn't guarantee you'll traverse nodes in index order, so different recursive branches will overwrite this variable and break your "continuous index" check.
  • AVL trees are designed for balanced ordered sets, not for efficiently combining interval-specific data like prefix sums, suffix sums, or max subarray sums—these are exactly the values you need to compute the answer quickly.

The right data structure for this problem is a Segment Tree—it's built specifically for O(logn) interval queries and updates, and can easily track all the values needed to calculate the maximum subarray sum in a range.

How the Segment Tree Works for This Problem

Each node in the segment tree will store four key values for its interval [start, end]:

  • total_sum: Sum of all elements in the interval
  • max_prefix: The maximum sum of a subarray starting at the left end of the interval
  • max_suffix: The maximum sum of a subarray ending at the right end of the interval
  • max_subarray: The maximum subarray sum anywhere within the interval

When merging two child nodes (left and right) into a parent node:

  1. total_sum = left.total_sum + right.total_sum
  2. max_prefix = max(left.max_prefix, left.total_sum + right.max_prefix) (either take the best prefix from the left, or the entire left plus the best prefix from the right)
  3. max_suffix = max(right.max_suffix, right.total_sum + left.max_suffix) (similar logic for the suffix)
  4. max_subarray = max(left.max_subarray, right.max_subarray, left.max_suffix + right.max_prefix) (the best subarray is either in the left, in the right, or crosses the boundary between left and right)

Example: Your Test Case

For your input array [-4990, -9230, -3269, -2047] (indices 1-4):

  • All elements are negative, so the maximum subarray is just the largest single element: -2047. The segment tree will correctly compute this because each leaf node's max_subarray is the element itself, and merging them will pick the largest value.

Sample Segment Tree Node Structure (C)

#include <climits>

struct SegmentTreeNode {
    int start, end;
    int total_sum;
    int max_prefix;
    int max_suffix;
    int max_subarray;
    SegmentTreeNode *left, *right;
    
    SegmentTreeNode(int s, int e) 
        : start(s), end(e), 
          total_sum(0), 
          max_prefix(INT_MIN), 
          max_suffix(INT_MIN), 
          max_subarray(INT_MIN),
          left(nullptr), right(nullptr) {}
};

Key Functions for the Segment Tree

Build Function

Recursively split the array into intervals until you reach single elements (leaf nodes), then merge the child nodes to compute the parent's values:

SegmentTreeNode* build(int arr[], int start, int end) {
    SegmentTreeNode* node = new SegmentTreeNode(start, end);
    if (start == end) {
        node->total_sum = arr[start];
        node->max_prefix = arr[start];
        node->max_suffix = arr[start];
        node->max_subarray = arr[start];
        return node;
    }
    int mid = (start + end) / 2;
    node->left = build(arr, start, mid);
    node->right = build(arr, mid + 1, end);
    
    // Merge child values
    node->total_sum = node->left->total_sum + node->right->total_sum;
    node->max_prefix = max(node->left->max_prefix, node->left->total_sum + node->right->max_prefix);
    node->max_suffix = max(node->right->max_suffix, node->right->total_sum + node->left->max_suffix);
    node->max_subarray = max({node->left->max_subarray, node->right->max_subarray, node->left->max_suffix + node->right->max_prefix});
    return node;
}

Query Function

Recursively find the segments that cover your query range [x, y], then merge their results to get the final maximum subarray sum:

// Helper struct to return merged results from queries
struct QueryResult {
    int total_sum;
    int max_prefix;
    int max_suffix;
    int max_subarray;
    QueryResult() : total_sum(0), max_prefix(INT_MIN), max_suffix(INT_MIN), max_subarray(INT_MIN) {}
    QueryResult(int ts, int mp, int ms, int msa) : total_sum(ts), max_prefix(mp), max_suffix(ms), max_subarray(msa) {}
};

QueryResult query(SegmentTreeNode* node, int x, int y) {
    if (node->end < x || node->start > y) {
        return QueryResult(); // Return invalid result
    }
    if (x <= node->start && node->end <= y) {
        return QueryResult(node->total_sum, node->max_prefix, node->max_suffix, node->max_subarray);
    }
    QueryResult leftRes = query(node->left, x, y);
    QueryResult rightRes = query(node->right, x, y);
    
    // Merge the two results
    QueryResult merged;
    merged.total_sum = leftRes.total_sum + rightRes.total_sum;
    merged.max_prefix = max(leftRes.max_prefix, leftRes.total_sum + rightRes.max_prefix);
    merged.max_suffix = max(rightRes.max_suffix, rightRes.total_sum + leftRes.max_suffix);
    merged.max_subarray = max({leftRes.max_subarray, rightRes.max_subarray, leftRes.max_suffix + rightRes.max_prefix});
    return merged;
}

Usage for Your Test Case

// Note: Adjust indices to 0-based if needed (your example uses 1-based)
int arr[] = {-4990, -9230, -3269, -2047};
SegmentTreeNode* root = build(arr, 0, 3);
QueryResult res = query(root, 0, 3); // For 1-based 1-4, use 0-3 in 0-based
printf("Max subarray sum: %d\n", res.max_subarray); // Outputs -2047

Why AVL Tree Isn't the Right Fit

AVL trees are great for maintaining a sorted collection with fast insertions/deletions, but they don't support the kind of interval merging needed for this problem. You can't efficiently track prefix/suffix/max subarray sums across arbitrary ranges with an AVL tree, so switching to a segment tree is the most straightforward way to get the O(logn) complexity you need.

内容的提问来源于stack exchange,提问作者Betty Teng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:37:38