分而治之——求最大子序列的和

分治法的运用条件:
1.原问题可以分解为若干与原问题的解;
2.子问题可以分解并可以求解;
3.子问题的解可以合并为原问题的解;
4.分解后的子问题应互相独立,即不包含重叠子问题

子序列的最大和只可能出现在三个位置:1、序列的左半部分;2、序列的右半部分;3、序列中横跨左右部分(一定包含中间元素)

   1、左半部分:递归调用该函数(左半部分子串),maxLeftSum递归到left==right;

   2、右半部分:递归调用该函数(右半部分子串)maxRightSum,递归到left==right;

   3、中间部分:从中间元素算起,其往左走的最大和maxLeftBorderSum+其往右走的最大和maxRightBorderSum,则中间结果的最大和为maxLeftBorderSum+ maxRightBorderSum;

   比较maxLeftSum,maxRightSum,maxRightBorderSum+ maxRightBorderSum中的最大值;

代码位置:

import java.util.Arrays;

public class maxArray {

	public static void main(String[] args) {
//将数组从中间分开得到两个子序列 最大值将会在左序列最大值、右序列最大值、跨中线序列最大值中产生
		int arr[] = new int[] {-1, 2, -5, 7, 8, -5 };
		
		System.out.println("最大子序列和为:"+maxArray.maxsum(arr));
		

	}



	public static int maxSubSum(int arr[], int left, int right) {
		if (left == right) {
			return arr[left];
		}
		int mid = (left + right) >>> 1; // 求中间位置
//递归找出左序列最大连续子序列和maxLeftSum
		int maxLeftSum = maxSubSum(arr, left, mid);
		
//递归找出右序列最大连续子序列和maxRightSum
		int maxRightSum = maxSubSum(arr, mid + 1, right);// 求右序列最大连续子序列
		int maxLeftBorderSum = 0, maxRightBorderSum = 0;// 跨边境左序列最大连续子序列,跨边境右序列最大连续子序列
		int leftBorderSum = 0, rightBorderSum = 0;
//跨中线最大连续子序列是由跨边境左序列最大连续子序列maxLeftBorderSum和跨边境右序列最大连续子序列maxRightBorderSum中产生
		for (int i = mid; i >= left; i--) {// 求跨边境左序列最大连续子序列maxLeftBorderSum
			leftBorderSum += arr[i];
			if (leftBorderSum > maxLeftBorderSum) {
				maxLeftBorderSum = leftBorderSum;
			}
		}

		for (int j = mid + 1; j <= right; j++) {// 求跨边境右序列最大连续子序列maxRightBorderSum
			leftBorderSum += arr[j];
			if (rightBorderSum > maxRightBorderSum) {
				maxRightBorderSum = rightBorderSum;
			}
		}
//递归找出右序列最大连续子序列和maxMidSum 
		int maxMidSum = maxLeftBorderSum + maxRightBorderSum;
		return max(maxLeftSum, maxRightSum, maxMidSum);

	}
//找最大值	
	 public static int max(int a, int b, int c) {
		int temp = Math.max(a, b);
		return Math.max(temp, c);

	}

	 public static int maxsum(int arr[]) {
		 return maxSubSum(arr,0,arr.length-1);

		}

	 
	 
	 





}

运行结果:

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
分而治之是一种常用的算法思想,可以用来解决最大子列和问题。在这种方法中,我们将问题分解成更小的子问题,并在每个子问题上递归地应用该方法。然后,我们将子问题的解合并起来,形成原始问题的解。 下面是使用分而治之方法解决最大子列和问题的Python代码: ```python def max_subarray_sum(arr, low, high): # 递归终止条件,当只有一个元素时返回该元素 if low == high: return arr[low] # 分治法的分解步骤,将问题分解为更小的子问题 mid = (low + high) // 2 left_max = max_subarray_sum(arr, low, mid) right_max = max_subarray_sum(arr, mid + 1, high) # 分治法的合并步骤,将子问题的解合并得到原始问题的解 cross_max = max_crossing_sum(arr, low, mid, high) # 返回左子数组最大子列和、右子数组最大子列和和跨越中点的最大子列和中的最大值 return max(left_max, right_max, cross_max) def max_crossing_sum(arr, low, mid, high): # 计算包含中点的左侧最大子列和 left_sum = float("-inf") curr_sum = 0 for i in range(mid, low - 1, -1): curr_sum += arr[i] if curr_sum > left_sum: left_sum = curr_sum # 计算包含中点的右侧最大子列和 right_sum = float("-inf") curr_sum = 0 for i in range(mid + 1, high + 1): curr_sum += arr[i] if curr_sum > right_sum: right_sum = curr_sum # 返回左侧最大子列和、右侧最大子列和和跨越中点的最大子列和的和 return left_sum + right_sum # 测试代码 arr = [-2, 11, -4, 13, -5, -2] max_sum = max_subarray_sum(arr, 0, len(arr) - 1) print(max_sum) ``` 这段代码通过递归地将问题分解为更小的子问题,并在每个子问题上应用该方法。然后,它将子问题的解合并起来,得到原始问题的解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平胸瑶女神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值