分治算法(Divide And Conquer)是解決規模龐大的問題的很好的思路,它經過下降問題的規模,造成若干個規模更小但形式相同的子問題,進行遞歸求解。在求解事後,將各個子問題的解合併起來,造成原問題的解。java
那麼它的大體流程主要分紅三步:算法
分治算法通常來講會採用遞歸法來進行實現,固然利用迭代法(好比for、while)也是能夠的。因此,咱們每每看到的遞歸算法從廣義上來講都是分治算法。無非就是有些遞歸算法將問題分解了若干個子問題,然而有些遞歸算法將問題分解成了一個子問題。數組
給定一個整數數組,找出總和最大的連續數列,並返回總和。ide
輸入: [-2,1,-3,4,-1,2,1,-5,4] 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。
本題比較優的解法是動態規劃,咱們嘗試用分治算法進行解決。code
咱們把數組分割成兩邊,那麼結果出現的區域,徹底在左邊、徹底在右邊、包括中間兩個節點的左右兩部分htm
public class Test1617 { public static void main(String[] args) { Test1617 test = new Test1617(); int[] nums = {-2,1,-3,4,-1,2,1,-5,4}; System.out.println(test.maxSubArray(nums)); } public int maxSubArray(int[] nums) { if (nums.length == 0) { return 0; } return divide(nums, 0,nums.length-1); } private int divide(int[] nums, int left, int right) { if (left == right) { return nums[left]; } int mid = (left + right) >> 1; // 1.左邊最大的子序列 int leftMaxSum = divide(nums, left, mid); // 2.右邊最大的子序列 int rightMaxSum = divide(nums, mid+1, right); // 3.最大數列和在中間 // 包括中間的,左邊部分最大 int sum = nums[mid]; int leftMidSum = sum; for (int i=mid-1; i>=left; i--) { sum += nums[i]; leftMidSum = Math.max(leftMidSum, sum); } // 包括中間的,右邊部分最大 sum = nums[mid+1]; int midRightSum = sum; for (int i=mid+2; i<=right; i++) { sum += nums[i]; midRightSum = Math.max(midRightSum, sum); } return Math.max(Math.max(leftMaxSum, rightMaxSum), leftMidSum+midRightSum); } }