最大子数组问题的Java实现

《算法导论》的第四章:分治策略中提到了最大子数组问题。采用分治策略可以得到一个渐进复杂性优于暴力解法的算法。文中使用Java实现该算法。

问题:你被许可可以在某一时刻买进某公司的股票,并在之后某个日期将其卖出,买进卖出都是在当天交易结束后进行。为了补偿这一限制,你可以了解股票将来的价格。你的目标是最大化收益。股票价格变化如下表:

012345678910111213141516
价格100113

110

851051028663811019410610179949097
变化——13-3-2520-3-16-231820-712-5-2215-47

用Java实现算法,代码如下:

public class Subarray {
	//如果最大子数组横跨左右部分数组
	public static int[] FindMaxCrossingSubarray(int[] A, int low, int mid, int high) {
		int[] result = new int[3];
		//从中间点向左遍历,找出左半部分过中点的最大子数组
		int sum = 0;
		int i;
		for (i=mid;i>=low;i--) {
			sum = sum + A[i];
			if (sum>result[2]) {
				result[2] = sum;
				result[0] = i;
			}
		}
		//从中间往右遍历,找出右半部分过中点的最大子数组
		sum = 0;
		result[2] = 0;
		for (i=mid;i<=high;i++) {
			sum = sum + A[i];
			if (sum>result[2]) {
				result[2] = sum;
				result[1] = i;
			}
		}
		//将左右两个子数组组合
		result[2] = 0;
		for (i = result[0];i<=result[1];i++) {
			result[2] = result[2] + A[i];
		}
		return result;
	}
	//将数组分成左右两个部分,依次计算左数组、右数组的最大子数组,再计算横跨左右部分的中间子数组,选择最大的输出
	public static int[] FindMaximumSubarray(int[] A, int low, int high) {
		int[] result = new int[3];
		int[] result_left = new int[3];
		int[] result_right = new int[3];
		int[] result_cross = new int[3];
		int mid = (int)(low+high)/2;
		//基本情况:数组中只有一个元素,则返回该数组
		if(low==high) {
			result[0]=low;
			result[1]=high;
			result[2]=A[low];
			return result;
		}
		//递归情况:数组中多于一个元素,依次计算三种情况下的最大子数组
		else {
			result_left = FindMaximumSubarray(A, low, mid);
			result_right = FindMaximumSubarray(A, mid+1, high);
			result_cross = FindMaxCrossingSubarray(A, low, mid, high);
			//比较三种情况的最大子数组,选择最大的输出
			if (result_left[2]>result_right[2] && result_left[2]>result_cross[2]) {
				return result_left;
			}
			else if (result_right[2]>result_left[2] && result_right[2]>result_cross[2]) {
				return result_right;
			}
			else {
				return result_cross;
			}
		}
	}
	public static void main(String[] args) {
		int[] result = new int[3];
		int[] A = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
		result = FindMaximumSubarray(A, 0, 15);
		System.out.print("The Maximum Subarray is : ");
		for(int i=result[0]; i<=result[1];i++) {
			System.out.print(A[i]+" ");
		}
		System.out.print("\nThe sum of the subarray is : "+result[2]);
	}
}

运行结果:

The Maximum Subarray is : 18 20 -7 12 
The sum of the subarray is : 43

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值