/* * 找出数组中最大子序列之和,分别以O(N^2),O(NlogN),O(N) 这3种时间复杂度求解 */ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MaxSubSumPro { class ArrayFactory { public static int[] RandomIntArray(int length) { return RandomIntArray(length, -1000, 999); } public static int[] RandomIntArray(int length, int minValue, int maxValue) { if (length <= 0 || minValue >= maxValue) { throw new ArgumentOutOfRangeException(); } Random ran = new Random(minValue + (maxValue - minValue) / 1000 * DateTime.Now.Millisecond); int[] arr = new int[length]; for (int i = 0; i < length; ++i) { arr[i] = ran.Next(minValue, maxValue); } return arr; } } class Printer<T> { public static void PrintArray(T[] array) { PrintArray(array, 10); } public static void PrintArray(T[] array, int maxItemInLine) { int temp = 0; for (int i = 0; i < array.Length; ++i) { Console.Write("{0,10} ", array[i].ToString()); ++temp; if (temp == maxItemInLine) { Console.WriteLine(); temp = 0; } } } } class MaxSubSum { /// <summary> /// O(N^2) /// </summary> /// <param name="array"></param> /// <returns></returns> public static long MaxSubSum1(int[] array) { long maxSum = Check(array); if (maxSum > 0) { maxSum = 0L; long sum; for (int i = 0; i < array.Length; ++i) { sum = 0L; for (int j = i; j < array.Length; ++j) { sum += array[j]; if (sum > maxSum) { maxSum = sum; } } } } Console.WriteLine("MaxSubSum1 output:" + maxSum); return maxSum; } /// <summary> /// O(NlogN) /// </summary> /// <param name="array"></param> /// <returns></returns> public static long MaxSubSum2(int[] array) { long maxSum = Check(array); if (maxSum > 0) { maxSum = MaxSubSum2_Recursion(array, 0, array.Length - 1); } Console.WriteLine("MaxSubSum2 output:" + maxSum); return maxSum; } private static long MaxSubSum2_Recursion(int[] array, int left, int right) { if (left == right) { return array[left]; } int mid = (left + right) / 2; long maxSumLeft = MaxSubSum2_Recursion(array, left, mid); long maxSumRight = MaxSubSum2_Recursion(array, mid + 1, right); long maxSumLeft_RightEdge = 0L; long maxSumRight_LeftEdge = 0L; long sum = 0L; for (int i = mid; i > left; --i) { sum += array[i]; if (sum > maxSumLeft_RightEdge) { maxSumLeft_RightEdge = sum; } } sum = 0L; for (int i = mid + 1; i < right; ++i) { sum += array[i]; if (sum > maxSumRight_LeftEdge) { maxSumRight_LeftEdge = sum; } } return Max3(maxSumLeft, maxSumRight, maxSumLeft_RightEdge + maxSumRight_LeftEdge); } private static long Max3(long a, long b, long c) { long r = a > b ? a : b; return r > c ? r : c; } /// <summary> /// O(N) /// </summary> /// <param name="array"></param> /// <returns></returns> public static long MaxSubSum3(int[] array) { long maxSum = Check(array); if (maxSum > 0) { maxSum = 0L; long sum = 0L; for (int i = 0; i < array.Length; ++i) { sum += array[i]; if (sum > maxSum) { maxSum = sum; } else if (sum < 0) { sum = 0; } } } Console.WriteLine("MaxSubSum3 output:" + maxSum); return maxSum; } private static int Check(int[] array) { if (array == null) { throw new ArgumentNullException("array"); } else if (array.Length == 0) { throw new ArgumentException("array has no items"); } else { int max = array[0]; foreach (int item in array) { if (max > 0) { break; } if (item > max) { max = item; } } return max; } } } class Test { static void Main(string[] args) { DateTime t1 = DateTime.Now; int[] a = ArrayFactory.RandomIntArray(100000); DateTime t2 = DateTime.Now; //Printer<int>.PrintArray(a); //DateTime t3 = DateTime.Now; Console.WriteLine("RandomIntArray Elapsed:" + (t2 - t1).ToString()); //Console.WriteLine("PrintArray Elapsed:" + (t3 - t2).ToString()); MaxSubSum.MaxSubSum1(a); DateTime t4 = DateTime.Now; MaxSubSum.MaxSubSum2(a); DateTime t5 = DateTime.Now; MaxSubSum.MaxSubSum3(a); DateTime t6 = DateTime.Now; Console.WriteLine("MaxSubSum1 Elapsed:" + (t4 - t2).ToString()); Console.WriteLine("MaxSubSum2 Elapsed:" + (t5 - t4).ToString()); Console.WriteLine("MaxSubSum3 Elapsed:" + (t6 - t5).ToString()); Console.WriteLine("-------------------------------------------"); DateTime t11 = DateTime.Now; int[] b = ArrayFactory.RandomIntArray(100000, -1000, 0); DateTime t12 = DateTime.Now; Console.WriteLine("RandomIntArray Elapsed:" + (t12 - t11).ToString()); MaxSubSum.MaxSubSum1(b); DateTime t13 = DateTime.Now; MaxSubSum.MaxSubSum2(b); DateTime t14 = DateTime.Now; MaxSubSum.MaxSubSum3(b); DateTime t15 = DateTime.Now; Console.WriteLine("MaxSubSum1 Elapsed:" + (t13 - t12).ToString()); Console.WriteLine("MaxSubSum2 Elapsed:" + (t14 - t13).ToString()); Console.WriteLine("MaxSubSum3 Elapsed:" + (t15 - t14).ToString()); } } } /*output RandomIntArray Elapsed:00:00:00.0050000 MaxSubSum1 output:185060 MaxSubSum2 output:185060 MaxSubSum3 output:185060 MaxSubSum1 Elapsed:00:00:36.5490000 MaxSubSum2 Elapsed:00:00:00.0220000 MaxSubSum3 Elapsed:00:00:00.0010000 ------------------------------------------- RandomIntArray Elapsed:00:00:00.0040000 MaxSubSum1 output:-1 MaxSubSum2 output:-1 MaxSubSum3 output:-1 MaxSubSum1 Elapsed:00:00:00.0010000 MaxSubSum2 Elapsed:00:00:00 MaxSubSum3 Elapsed:00:00:00.0010000 */