分治法(递归的解决问题)
分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。
可使用分治法求解的一些经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔
分治算法 - 最大子数组问题
求得价格波动 最大子数组,及和最大的子数组
1,暴力求解
[csharp] view plain copy
- private readonly int[] _priceArray = new[] {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
- private void Violence(int[] priceArray)
- {
- int total = priceArray[0];
- int startIndex = 0;
- int endIndex = 0;
- for (int i = 0; i < priceArray.Length; i++)
- {
- for (int j = i; j < priceArray.Length; j++)
- {
- //确定一个子数组
- int totalTemp = 0;
- for (int k = i; k < j + 1; k++)
- {
- totalTemp += priceArray[k];
- }
- if (totalTemp > total)
- {
- total = totalTemp;
- startIndex = i;
- endIndex = j;
- }
- }
- }
- "---" + endIndex); // 7---10
- }
2,分治法
[csharp] view plain copy
- public struct SubArray
- {
- public int StartIndex;
- public int EndIndex;
- public int Total;
- }
- private SubArray DivideAndRule(int low, int high, int[] priceArray)
- {
- if (low == high)
- {
- new SubArray();
- subArray.StartIndex = low;
- subArray.EndIndex = high;
- subArray.Total = priceArray[low];
- return subArray;
- }
- int mid = (low + high)/2; //[low,mid] [mid+1,high]
- //1在低区间
- SubArray lowSubArray = DivideAndRule(low, mid, priceArray);
- //2在高区间
- SubArray highSubArray = DivideAndRule(mid + 1, high, priceArray);
- //3跨两区间
- int total1 = priceArray[mid];
- int startIndex = mid;
- int endIndex = mid + 1;
- int totalTemp = 0;
- for (int i = mid; i >= low; i--)
- {
- totalTemp += priceArray[i];
- if (totalTemp > total1)
- {
- total1 = totalTemp;
- startIndex = i;
- }
- }
- int total2 = priceArray[mid + 1];
- totalTemp = 0;
- for (int i = mid + 1; i <= high; i++)
- {
- totalTemp += priceArray[i];
- if (totalTemp > total2)
- {
- total2 = totalTemp;
- endIndex = i;
- }
- }
- new SubArray()
- {
- StartIndex = startIndex,
- EndIndex = endIndex,
- Total = total1 + total2
- };
- if (lowSubArray.Total > currSubArray.Total && lowSubArray.Total > highSubArray.Total)
- {
- return lowSubArray;
- }
- if (currSubArray.Total > lowSubArray.Total && currSubArray.Total > highSubArray.Total)
- {
- return currSubArray;
- }
- return highSubArray;
- }