连续子数组的最大和

  1. 有一个整数数组,求出连续子数组的和的最大值。
  2. 有一个首尾相连的整数数组,求出连续子数组的和的最大值。
  3. 在数组中,数字减去它右边的数字得到一个数对之差。求所有数对之差的最大值。

1、思路:

  动态规划思路:用函数f(i)表示以第i个数字结尾的子数组的最大和。当f(i-1)<0时,则以第i个数字结尾的子数组就是第i个数字本身;当f(i-1)>0时,f(i)=f(i-1)+i。虽然我们用递归的方式分析动态规划的问题,但都会基于循环去编码。

GreatestSumOfSubArray
 1 bool g_InvalidInput = false;
 2 
 3 int FindGreatestSumOfSubArray(int *pData, int nLength)
 4 {
 5     if((pData == NULL) || (nLength <= 0))
 6     {
 7         g_InvalidInput = true;
 8         return 0;
 9     }
10 
11     g_InvalidInput = false;
12 
13     int nCurSum = 0;
14     int nGreatestSum = 0x80000000;
15     for(int i = 0; i < nLength; ++i)
16     {
17         if(nCurSum <= 0)
18             nCurSum = pData[i];
19         else
20             nCurSum += pData[i];
21 
22         if(nCurSum > nGreatestSum)
23             nGreatestSum = nCurSum;
24     }
25 
26     return nGreatestSum;
27 } 

 2、思路:

  最优解包含两种情况:一种是没有跨过a[n-1]到a[0],即第一种解法;另一种是跨过a[n-1]到a[0]的,采取的方法先求原数组的最小数列,再用全部元素的和减去最小数列,即为最大和。

FindMaxSumCircle
 1 //环形数组求最大子数组的和
 2 int MaxSum(int *a , int n)
 3 {
 4     int i , sum , max1 , max2 , dp, min;
 5     dp = max1 = a[0];
 6     for(i = 1 ; i < n ; ++i)   //最优解没有跨过a[n-1]到a[0],即原问题,非环形数组
 7     {
 8         if(dp < 0)
 9             dp = a[i];
10         else
11             dp += a[i];
12         if(dp > max1)
13             max1 = dp;
14     }
15     sum = min = dp = a[0];
16     for(i = 1 ; i < n ; ++i)   //可以将原问题转化为数组的最小子段和问题,再用数组全部元素的和减去最小子段和,那么结果一定是跨过a[n-1]到a[0]情况中最大的子段和
17     {
18         if(dp > 0)
19             dp = a[i];
20         else
21             dp += a[i];
22         if(dp < min)
23             min = dp;
24         sum += a[i];
25     }
26     max2 = sum - min;    //数组全部元素的和减去最小子段和
27     return max1 > max2 ? max1 : max2;;     //返回一个较大值
28 }

 3、思路:

  转化为求解子数组最大和的问题。a1-a4=(a1-a2)+(a2-a3)+(a3-a4)。

 1 int MaxDiff_Solution2(int numbers[], unsigned length)
 2 {
 3     if(numbers == NULL || length < 2)
 4         return 0;
 5  
 6     int* diff = new int[length - 1];
 7     for(int i = 1; i < length; ++i)
 8         diff[i - 1] = numbers[i - 1] - numbers[i];
 9  
10     int currentSum = 0;
11     int greatestSum = 0x80000000;
12     for(int i = 0; i < length - 1; ++i)
13     {
14         if(currentSum <= 0)
15             currentSum = diff[i];
16         else
17             currentSum += diff[i];
18  
19         if(currentSum > greatestSum)
20             greatestSum = currentSum;
21     }
22  
23     delete[] diff;
24  
25     return greatestSum;
26 } 
MaxDiff

  另外一种动态规划的解法,传送门:http://zhedahht.blog.163.com/blog/static/2541117420116135376632/

posted on 2013-03-23 11:06  月moon鸟  阅读(246)  评论(0编辑  收藏  举报

导航