1. 最大子数组和问题与Kadane算法实战
1.1 问题背景与核心思路
最大子数组和问题(Maximum Subarray Problem)是算法领域的经典问题,给定一个数组(或字符串),我们需要找到一个连续子数组(子串),使得该子数组的元素和最大。这个问题在实际中有广泛应用,比如金融分析中的最大收益区间、信号处理中的最大能量区间等。
Kadane算法是解决该问题的经典动态规划算法,由卡内基梅隆大学的Jay Kadane教授在1984年提出。它的核心思想是通过一次遍历数组,在每个位置计算以该位置元素结尾的最大子数组和,同时维护一个全局最大值。
1.2 算法实现细节解析
让我们深入分析提供的代码实现:
cpp复制int maximumCostSubstring(string s, string chars, vector<int>& vals) {
int mapping[26]{};
iota(mapping, mapping + 26, 1);
for (int i = 0; i < chars.length(); i++)
mapping[chars[i] - 'a'] = vals[i];
int ans = 0, f = 0;
for (char c : s) {
f = max(f, 0) + mapping[c - 'a'];
ans = max(ans, f);
}
return ans;
}
关键点解析:
-
字符到值的映射建立:
- 默认情况下,字母a-z映射为1-26(
iota(mapping, mapping + 26, 1)) - 可以通过
chars和vals参数覆盖特定字符的映射值
- 默认情况下,字母a-z映射为1-26(
-
Kadane算法核心逻辑:
f表示以当前字符结尾的最大子串和f = max(f, 0) + mapping[c - 'a']是关键递推式:max(f, 0):如果之前的子串和为负,则舍弃(从当前字符重新开始)+ mapping[c - 'a']:加上当前字符的值
ans维护全局最大值
-
允许空子串的特殊处理:
- 初始化
ans = 0,表示空子串的和为0 - 如果所有子串和都为负,算法会返回0(空子串)
- 初始化
1.3 算法复杂度分析
- 时间复杂度:O(n),只需一次遍历字符串
- 空间复杂度:O(1),仅使用固定大小的额外空间(26个字母的映射表)
1.4 实际应用与变种
Kadane算法在实际中有多种变体:
- 不允许空子串:初始化`an
