总体思想:将大的拆成小的,将小的拆成更小的,一直拆分到很微量的一个状态,再研究它的效果。
分治,就是分而治之,就是把一个问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题解的合并,其中子问题的解是独立互不影响的。
在分治算法中常用递归的方式实现(也有非递归的方式),具体描述为:
①分:递归的解决较小的问题(到终止层或者可以解决的时候停下);
②治:递归求解,如果问题够小直接求解;
③合并:将子问题的解构建父类问题。
分治与递归的区别:分治是一种思想,而递归是一种方法工具,这种方法通过自己调用自己形成一个来回的过程,而分治就是利用了多次这样来回的过程。
分治法的经典应用为快速排序、归并排序、求最近点对等。
class Solution {
public int maxSubArray(int[] nums) {
return maxSubArray3(nums,0,nums.length-1);
}
public int maxSubArray3(int[] nums,int left,int right) {
if(left == right){
return nums[left];
}else {
int mid = (left+right)/2;
int leftMax = maxSubArray3(nums,left,mid);
int rightMax = maxSubArray3(nums,mid+1,right);
int midMax = maxSubArray3Helper(nums,left,right,mid);
if(leftMax >= rightMax && leftMax >= midMax){
return leftMax;
}else if(rightMax >= leftMax && rightMax >= midMax){
return rightMax;
}else {
return midMax;
}
}
}
public int maxSubArray3Helper(int[] nums,int left,int right,int mid) {
int leftVal = Integer.MIN_VALUE;
int rightVal = Integer.MIN_VALUE;
int sum = 0;
for(int i=mid;i>=left;i--){
sum += nums[i];
if(sum > leftVal){
leftVal = sum;
}
}
sum = 0;
for(int j=mid+1;j<=right;j++){
sum += nums[j];
if(sum > rightVal){
rightVal = sum;
}
}
return leftVal+rightVal;
}
}