java 算法之分治策略求最大子数组问题

5 篇文章 0 订阅

    首先,我们可以使用暴力方式求解最大子数组,编码思路:第一层循环遍历该数组,然后使用第二层循环寻找子数组,用第一层循环的 i 变量来记录寻找位置,然后向后依次遍历,进行累加计算,判断出最大值;java代码如下:

    //暴力方式求解(遍历)

    static int findMaxArray(int[] arr, int lenth) {
int maxSum = 0;
int sum;
for (int i = 0; i < arr.length; i++) {
sum = 0;
for (int j = i; j < lenth; j++) {
sum += arr[j];
if (sum > maxSum) {
maxSum = sum;
}
}
}
return maxSum;

}


暴力方式有点消耗时间,当然,这是不可容忍的,所以,分治策略,,,,诞生了

简单说说分治策略来解决这个问题,首先,我们将整个数组从mid对分为两组,分为三种情况,low--mid,mid+1--high,low--mid,在左右两边的情况中,我们可以简单的使用递归求解,不断的拆分,直到它被拆分为单个数字弹出;若子数组处于第二种情况,即i < mid <j,在这种情况下,我们从mid将其拆分,分别向左右检索,两边检索出来的值的和则为最终解;java代码如下:

    
//分治策略求解;
//分治策略,分三种情况:将父数组分为low -- mid ---high 三部分
//1、子数组完全位于父数组 low --- mid
//2、子数组完全位于 父数组 mid+1 --- high
//3、子数组位于 low --- high 之间,跨越 mid 
static int findMaxCrossingArray(int[] arr, int low, int mid, int high) {
int sum = 0;
int leftSum = arr[mid];
for (int i = mid; i >= low; i--) {
sum += arr[i];
if (sum > leftSum) {
leftSum = sum;
}
}


sum = 0;
int rightSum = arr[mid + 1];
for (int i = (mid + 1); i <= high; i++) {
sum += arr[i];
if (sum > rightSum) {
rightSum = sum;
}
}


return (leftSum + rightSum);
}


static int findMaxArray(int[] arr, int low, int high) {
if (low == high) {
return arr[low];
}
int mid = (low + high) / 2;
int leftMax = findMaxArray(arr, low, mid);
int rightMax = findMaxArray(arr, mid + 1, high);
int crossMax = findMaxCrossingArray(arr, low, mid, high);


if (leftMax > rightMax && leftMax > crossMax) {
return leftMax;
} else if (rightMax > leftMax && rightMax > crossMax) {
return rightMax;
} else {
return crossMax;
}


}


最后附上main函数进行检测:

public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = {1,-2,-1,2}; //测试数据
System.out.println(findMaxArray(array, array.length));
System.out.println(findMaxArray(array, 0, array.length-1));
}

PS:本次实验仅仅是简单的提供思路和算法实现,具体时间复杂度请各位友友提供超长数据进行测试,以选择最优方式实现。

感谢大家的支持!!!若有感兴趣的友友们请点击关注,谢谢。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值