分治法(递归的解决问题)

分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。


可使用分治法求解的一些经典问题

(1)二分搜索

(2)大整数乘法

(3)Strassen矩阵乘法

(4)棋盘覆盖

(5)合并排序

(6)快速排序

(7)线性时间选择

(8)最接近点对问题

(9)循环赛日程表

(10)汉诺塔


分治算法 - 最大子数组问题

C#内功修炼(算法)——分治法(一)_分治法

求得价格波动 最大子数组,及和最大的子数组

1,暴力求解

[csharp]  ​​view plain​​  ​​copy​​



  1. private readonly int[] _priceArray = new[] {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};  
  2.   
  3. private void Violence(int[] priceArray)  
  4.   {  
  5. int total = priceArray[0];  
  6. int startIndex = 0;  
  7. int endIndex = 0;  
  8.   
  9. for (int i = 0; i < priceArray.Length; i++)  
  10.       {  
  11. for (int j = i; j < priceArray.Length; j++)  
  12.           {  
  13. //确定一个子数组  
  14.   
  15. int totalTemp = 0;  
  16. for (int k = i; k < j + 1; k++)  
  17.               {  
  18.                   totalTemp += priceArray[k];  
  19.               }  
  20.   
  21. if (totalTemp > total)  
  22.               {  
  23.                   total = totalTemp;  
  24.                   startIndex = i;  
  25.                   endIndex = j;  
  26.               }  
  27.           }  
  28.       }  
  29.   
  30. "---" + endIndex);   // 7---10  
  31.   }  

2,分治法

[csharp]  ​​view plain​​  ​​copy​​



  1. public struct SubArray  
  2.    {  
  3. public int StartIndex;  
  4. public int EndIndex;  
  5. public int Total;  
  6.    }  
  7.   
  8. private SubArray DivideAndRule(int low, int high, int[] priceArray)  
  9.    {  
  10. if (low == high)  
  11.        {  
  12. new SubArray();  
  13.            subArray.StartIndex = low;  
  14.            subArray.EndIndex = high;  
  15.            subArray.Total = priceArray[low];  
  16.   
  17. return subArray;  
  18.        }  
  19.   
  20. int mid = (low + high)/2; //[low,mid] [mid+1,high]  
  21.   
  22. //1在低区间  
  23.        SubArray lowSubArray = DivideAndRule(low, mid, priceArray);  
  24.   
  25. //2在高区间  
  26.        SubArray highSubArray = DivideAndRule(mid + 1, high, priceArray);  
  27.   
  28. //3跨两区间  
  29. int total1 = priceArray[mid];  
  30. int startIndex = mid;  
  31. int endIndex = mid + 1;  
  32. int totalTemp = 0;  
  33.   
  34. for (int i = mid; i >= low; i--)  
  35.        {  
  36.            totalTemp += priceArray[i];  
  37. if (totalTemp > total1)  
  38.            {  
  39.                total1 = totalTemp;  
  40.                startIndex = i;  
  41.            }  
  42.        }  
  43.   
  44. int total2 = priceArray[mid + 1];  
  45.        totalTemp = 0;  
  46. for (int i = mid + 1; i <= high; i++)  
  47.        {  
  48.            totalTemp += priceArray[i];  
  49. if (totalTemp > total2)  
  50.            {  
  51.                total2 = totalTemp;  
  52.                endIndex = i;  
  53.            }  
  54.        }  
  55.   
  56. new SubArray()  
  57.        {  
  58.            StartIndex = startIndex,  
  59.            EndIndex = endIndex,  
  60.            Total = total1 + total2  
  61.        };  
  62.   
  63. if (lowSubArray.Total > currSubArray.Total && lowSubArray.Total > highSubArray.Total)  
  64.        {  
  65. return lowSubArray;  
  66.        }  
  67. if (currSubArray.Total > lowSubArray.Total && currSubArray.Total > highSubArray.Total)  
  68.        {  
  69. return currSubArray;  
  70.        }  
  71.   
  72. return highSubArray;  
  73.    }