以下是一个算法设计,能够在 C# 数组中找出最大范围(子数组),并计算该范围内的元素之和。这个问题是典型的最大子数组问题,可以使用 Kadane 算法 来高效解决,其时间复杂度为 O(n)。
算法思想
- 遍历数组,同时记录:当前的子数组和(currentSum)。最大的子数组和(maxSum)。最大子数组的起始和结束索引(startIndex 和 endIndex)。
- 如果 currentSum 小于 0,重新从当前元素开始计算子数组。
- 如果 currentSum 大于 maxSum,更新最大和以及对应的范围。
代码实现
using System;
class Program
{
static void Main()
{
// 输入数组
int[] array = { -2, 1, -3, 4, -1, 2, 1, -5, 4 };
// 找到最大范围及其和
var result = FindMaxSubarray(array);
// 输出结果
Console.WriteLine($"最大范围: [{result.StartIndex}, {result.EndIndex}]");
Console.WriteLine($"范围内的元素之和: {result.MaxSum}");
Console.WriteLine("子数组: " + string.Join(", ", result.Subarray));
}
static (int StartIndex, int EndIndex, int MaxSum, int[] Subarray) FindMaxSubarray(int[] array)
{
int maxSum = int.MinValue;
int currentSum = 0;
int start = 0, tempStart = 0, end = 0;
for (int i = 0; i < array.Length; i++)
{
currentSum += array[i];
// 更新最大和及范围
if (currentSum > maxSum)
{
maxSum = currentSum;
start = tempStart;
end = i;
}
// 如果当前和小于0,重新开始计算子数组
if (currentSum < 0)
{
currentSum = 0;
tempStart = i + 1;
}
}
// 提取子数组
int[] subarray = new int[end - start + 1];
Array.Copy(array, start, subarray, 0, end - start + 1);
return (start, end, maxSum, subarray);
}
}
代码解析
- 输入数组:
- 示例数组为 { -2, 1, -3, 4, -1, 2, 1, -5, 4 }。
- Kadane 算法:
- 使用 currentSum 记录当前子数组的和。
- 当 currentSum > maxSum 时,更新最大和 maxSum 以及范围索引。
- 重置条件:
- 当 currentSum < 0 时,重置 currentSum 为 0 并移动临时起点 tempStart。
- 提取子数组:
- 使用 Array.Copy 方法提取出最大范围的子数组。
运行结果
对于输入数组 { -2, 1, -3, 4, -1, 2, 1, -5, 4 },输出结果为:
最大范围: [3, 6]
范围内的元素之和: 6
子数组: 4, -1, 2, 1
时间和空间复杂度
- 时间复杂度:O(n),只需遍历数组一次。
- 空间复杂度:O(k),其中 k 是最大子数组的长度,用于存储子数组。
算法优势
- 高效:相比暴力解法的 O(n2) 或 O(n3) 时间复杂度,Kadane 算法性能更优。
- 简洁:通过单次遍历即可找到最大范围和其元素和。
- 易用:适用于绝大多数包含正负数的数组问题。