分治法求最大子数组
最大子数组(分治法)
解题思路:
将数组分成两份,最大子数组(元素之和最大)只有三种情况:
- (1)最大子数组在mid左边,即:startIndex和endIndex都在mid左边
- (2)最大子数组一半在左边,一半在右边,即:startIndex在 mid左边,endIndex在mid右边
- (3)最大子数组在mid右边,即:startIndex和endIndex都在mid右边
那么比较三种情况下的最大子数组的结果接可以了,最终得出最大子数组
那么继续运用递归,继续给mid左边和右边进行分治求解,将复杂的问题进行简化,以此降低了代码的时间复杂度,提高了程序的运行效率。
代码实现
namespace _分治法求最大子数组
{
class Program
{
struct SubArray
{
public int startIndex;
public int endIndex;
public int total;
}
public static void Main(string[] args)
{
int[] priceArray = new int[] { 100, 120, 140, 50, 63, 89, 150, 162, 186, 20,
90, 48, 75, 97, 98 };
int[] priceFluctuationArray = new int[priceArray.Length - 1]; // 前后相减之后的差组成的数组
for (int i = 1; i < priceArray.Length; i++)
{
priceFluctuationArray[i - 1] = priceArray[i] - priceArray[i - 1];
}
SubArray subArray = GetMaxSubArray(0, priceFluctuationArray.Length - 1,
priceFluctuationArray);
Console.WriteLine(subArray.startIndex);
Console.WriteLine(subArray.endIndex+1);
}
static SubArray GetMaxSubArray(int low, int high, int[] array) // 这个方法是用来取得array这个数组从low到high之间的最大子数组
{
if (low == high)
{
SubArray subarray;
subarray.startIndex= low;
subarray.endIndex= high;
subarray.total = array[low];
return subarray;
}
int mid = (low + high) / 2; // 地区间low到mid ,高区间mid+1 到high
SubArray subArray1 = GetMaxSubArray(low, mid, array);
SubArray subArray2 = GetMaxSubArray(mid + 1, high, array);
// 从low-mid找到最大子数组i-mid
int total1 = array[mid];
int startIndex = mid;
int totalTemp = 0;
for(int i = mid; i >= low; i--)
{
totalTemp+= array[i];
if (totalTemp > total1)
{
total1 = totalTemp;
startIndex = i;
}
}
// 从mid-high找到最大子数组mid+1-j
int total2;
total2 = array[mid+ 1];
int endIndex = mid + 1;
totalTemp= 0;
for(int j = mid + 1; j <= high; j++)
{
totalTemp+= array[j];
if(totalTemp> total2)
{
total2 = totalTemp;
endIndex = j;
}
}
SubArray subarray3;
subarray3.startIndex = startIndex;
subarray3.endIndex= endIndex;
subarray3.total = total1 + total2;
if (subArray1.total >= subArray2.total && subArray1.total >= subarray3.total)
{
return subArray1;
}
else if (subArray2.total >= subArray1.total && subArray2.total >=
subarray3.total)
{
return subArray2;
}
else
{
return subarray3;
}
}
}
}