我正在尝试在C#中开发最大子数组问题
我的代码是
try
{
int[] Values = { 9, 1, 4, 15, -5, -41, -8, 78, 145, 14 };//Will be executed once '1'
int StartIndex = 0;//Will be executed once '1'
double Sum = 0;//Will be executed once '1'
double Temp = 0;//Will be executed once '1'
double Max = 0;//Will be executed once '1'
do
{
for (int i = 0; i < Values.Length; i++)//1+(N+1)+N
{
Sum = Values[StartIndex];
if (StartIndex < i)
{
for (int j = StartIndex+1; j <= i; j++)
{
Sum += Values[j];
}
if (Sum > Temp)
{
Max = Sum;
Temp = Sum;
}
}
}
StartIndex++;
} while (StartIndex<Values.Length);
MessageBox.Show("The Max Value is " + Max);
}
catch { }
我想知道这是否是解决此算法的最佳方法,因为我正在努力将时间复杂度降至最低
谢谢大家的时间
答案 0 :(得分:1)
在Inroduction to Algorithms: CLRS中描述了分而治之的实现与O(N * logN)的复杂性,第4章分而治之4.1最大子阵列问题。 C#port from。
class Program {
static void Main(string[] args) {
int[] values = { 9, 1, 4, 15, -5, -41, -8, 78, 145, 14 };
Console.WriteLine(FindMaxSubarray(values, 0, values.Length - 1));
}
public struct MaxSubArray {
public int Low;
public int High;
public int Sum;
public override string ToString() {
return String.Format("From: {0} To: {1} Sum: {2}", Low, High, Sum);
}
}
private static MaxSubArray FindMaxSubarray(int[] a, int low, int high) {
var res = new MaxSubArray {
Low = low,
High = high,
Sum = a[low]
};
if (low == high) return res;
var mid = (low + high) / 2;
var leftSubarray = FindMaxSubarray(a, low, mid);
var rightSubarray = FindMaxSubarray(a, mid + 1, high);
var crossingSubarray = FindMaxCrossingSubarray(a, low, mid, high);
if (leftSubarray.Sum >= rightSubarray.Sum &&
leftSubarray.Sum >= crossingSubarray.Sum)
return leftSubarray;
if (rightSubarray.Sum >= leftSubarray.Sum &&
rightSubarray.Sum >= crossingSubarray.Sum)
return rightSubarray;
return crossingSubarray;
}
private static MaxSubArray FindMaxCrossingSubarray(int[] a, int low, int mid, int high) {
var maxLeft = 0;
var maxRight = 0;
var leftSubarraySum = Int32.MinValue;
var rightSubarraySum = Int32.MinValue;
var sum = 0;
for (var i = mid; i >= low; i--) {
sum += a[i];
if (sum <= leftSubarraySum) continue;
leftSubarraySum = sum;
maxLeft = i;
}
sum = 0;
for (var j = mid + 1; j <= high; j++) {
sum += a[j];
if (sum <= rightSubarraySum) continue;
rightSubarraySum = sum;
maxRight = j;
}
return new MaxSubArray {
Low = maxLeft,
High = maxRight,
Sum = leftSubarraySum + rightSubarraySum
};
}
}
答案 1 :(得分:1)
代码的时间复杂度为O(n^3)
,但您可以使用两个renovations进行改进,并将其更改为O(N^2)
。但是动态编程设计的algorithm或this更好。
this解决方案在矩阵数组中解决它。 注意:最大默认值应设置为无限负值。
这是来自wiki的代码:
在整个数组由负数组成的情况下,不允许返回零长度子数组的问题的变体可以使用以下代码解决,在此处用C ++编程语言表示。
int sequence(std::vector<int>& numbers)
{
// Initialize variables here
int max_so_far = numbers[0], max_ending_here = numbers[0];
size_t begin = 0;
size_t begin_temp = 0;
size_t end = 0;
// Find sequence by looping through
for(size_t i = 1; i < numbers.size(); i++)
{
// calculate max_ending_here
if(max_ending_here < 0)
{
max_ending_here = numbers[i];
begin_temp = i;
}
else
{
max_ending_here += numbers[i];
}
// calculate max_so_far
if(max_ending_here > max_so_far )
{
max_so_far = max_ending_here;
begin = begin_temp;
end = i;
}
}
return max_so_far ;
}
答案 2 :(得分:1)
这里有一个O(N)算法:http://en.wikipedia.org/wiki/Maximum_subarray_problem
它实际上并没有给你子数组,只是子数组的最大值。
注意输入数组必须包含至少一个正(非零)数字的重要限制。
我修改了它以返回范围以及最大值:
using System;
namespace Demo
{
public static class Program
{
public static void Main(string[] args)
{
//int[] numbers = new[] { -2, 1, -3, 4, -1, 2, 1, -5, 4 };
//int[] numbers = new[] { 1, 1, 1, 1, 1, 1, 1, 1 };
int[] numbers = new[] {9, 1, 4, 15, -5, -41, -8, 78, 145, 14};
var result = FindMaximumSubarray(numbers);
Console.WriteLine("Range = {0}..{1}, Value = {2}", result.StartIndex, result.EndIndex, result.Value);
}
public static MaximumSubarray FindMaximumSubarray(int[] numbers)
{
int maxSoFar = numbers[0];
int maxEndingHere = numbers[0];
int begin = 0;
int startIndex = 0;
int endIndex = 0;
for (int i = 1; i < numbers.Length; ++i)
{
if (maxEndingHere < 0)
{
maxEndingHere = numbers[i];
begin = i;
}
else
{
maxEndingHere += numbers[i];
}
if (maxEndingHere > maxSoFar)
{
startIndex = begin;
endIndex = i;
maxSoFar = maxEndingHere;
}
}
return new MaximumSubarray
{
StartIndex = startIndex,
EndIndex = endIndex,
Value = maxSoFar
};
}
public struct MaximumSubarray
{
public int StartIndex;
public int EndIndex;
public int Value;
}
}
}
答案 3 :(得分:0)
试试这个
static void Main()
{
try
{
int[] Values = { 9, 1, 4, 15, -5, -41, -8, 78, 145, 14 };//Will be executed once '1'
int max_ending_here = 0;
int max_so_far = 0;
foreach(int x in Values)
{
max_ending_here = Math.Max(0, max_ending_here + x);
max_so_far = Math.Max(max_so_far, max_ending_here);
}
Console.WriteLine("The Max Value is " + max_so_far);
Console.ReadKey();
}
catch { }
}