分治法,采用一种“分治(divide-and-conquer)”的策略。其想法是把问题分成两个大致相等的子问题,然后递归地对他们求解,这是“分”的含义。“治”阶段将两个子问题修补到一起并外加少量附加工作,最后得到整个问题的答案。分治法的思想其实是递归。
【求最大子序列和】在最大子序列和问题中,最大子序列和可能出现在三处。可能是整个数组的左半部,可能是整个数组的右半部,也有可能是跨越中间元素从而位于左右两部分之间。前面两种情况很容易使用递归来求解,第三种情况可以通过前半部分(包含左半部分最后一个元素)和最大和以及后半部分(包含有半部分第一个元素)最大和,再把二者相加得到。最后三种情况得到的三个值中,最大者就是我们所要的结果。
<span style="font-size:18px;"> public static int maxSum(int[] a,int left,int right) { if(left==right)return a[left]; int center=(left+right)/2; int maxLeftSum=maxSum(a,left,center); int maxRightSum=maxSum(a,center+1,right); int maxLeftBorderSum=0,leftSum=0; for(int i=center;i>=left;i--) { leftSum+=a[i]; if(leftSum>maxLeftBorderSum) maxLeftBorderSum=leftSum; } int maxRightBorderSum=0,rightSum=0; for(int i=center+1;i<=right;i++) { rightSum+=a[i]; if(rightSum>maxRightBorderSum) maxRightBorderSum=rightSum; } return Math.max(maxRightBorderSum+maxLeftBorderSum,Math.max(maxLeftSum,maxRightSum)); }</span>
【求最大子序列乘积】
Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6
.
对于求最大子序列乘积问题,思路和最大子序列和问题差不多,不过在第三种情况的求解时,稍微复杂一点。为什么会复杂一点呢?原因是符号问题,所以在求第三种情况时,除了要求解最大乘积,还要求解最小乘积。这个道理是很显然的。
<span style="font-size:18px;"> public static int maxProduct(int[] a) { return maxProduct(a,0,a.length-1); } public static int maxProduct(int[] a,int left,int right) { if(left==right)return a[left]; int center=(left+right)/2; int maxLeftProduct=maxProduct(a,left,center); int maxRightProduct=maxProduct(a,center+1,right); int maxLeftBorderProduct=a[center],leftProduct=1; for(int i=center;i>=left;i--) { leftProduct*=a[i]; if(leftProduct>maxLeftBorderProduct) maxLeftBorderProduct=leftProduct; } int minLeftBorderProduct=a[center]; leftProduct=1; for(int i=center;i>=left;i--) { leftProduct*=a[i]; if(leftProduct<minLeftBorderProduct) minLeftBorderProduct=leftProduct; } int maxRightBorderProduct=a[center+1],rightProduct=1; for(int i=center+1;i<=right;i++) { rightProduct*=a[i]; if(rightProduct>maxRightBorderProduct) maxRightBorderProduct=rightProduct; } int minRightBorderProduct=a[center+1]; rightProduct=1; for(int i=center+1;i<=right;i++) { rightProduct*=a[i]; if(rightProduct<minRightBorderProduct) minRightBorderProduct=rightProduct; } int max1=Math.max(maxLeftProduct, maxRightProduct); int max2=0; if(maxLeftBorderProduct>0&& maxRightBorderProduct>0)max2=maxRightBorderProduct*maxLeftBorderProduct; else if(maxLeftBorderProduct<0&& maxRightBorderProduct<0)max2=maxRightBorderProduct*maxLeftBorderProduct; else max2=Math.max(maxRightBorderProduct, minLeftBorderProduct); int max3=Integer.MIN_VALUE; if(minLeftBorderProduct<0&& minRightBorderProduct<0)max3=minRightBorderProduct*minLeftBorderProduct; return Math.max(max1,Math.max(max2, max3)); }</span>
时间: 2024-11-02 02:38:10