20
2018
08

最大子数组

寻找数组A的和最大的非空连续子数组。

就是之前的最大子串和、积

这个问题暴力解法,时间复杂度是O(n^2),之前的算法时间复杂度是O(n),这里使用分治策略,时间复杂度是O(nlgn)。

代码如下:

var a = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7];
var b = findMaximumSubArray(a, 0, a.length-1);
console.log('数组:',a.join(','));
console.log('结果',b.join(','));
console.log('最大子数组:',a.slice(b[0], b[1]+1).join(','));

function findMaxCrossingSubArray(a, low, mid, high){
	var leftSum = -Infinity;
	var sum = 0;
	var maxLeft = mid;
	for(var i = mid; i >= low; i--){
		sum = sum + a[i];
		if(sum > leftSum){
			leftSum = sum;
			maxLeft = i;
		}
	}
	var rightSum = -Infinity;
	sum = 0;
	var maxRight = mid;
	for(var j = mid + 1; j <= high; j++){
		sum = sum + a[j];
		if(sum > rightSum){
			rightSum = sum;
			maxRight = j;
		}
	}
	return [maxLeft, maxRight, leftSum + rightSum];
}

function findMaximumSubArray(a, low, high){
	if(high == low){
		return [low, high, a[low]];
	} else {
		var mid = Math.floor((low + high) / 2);
		var left = findMaximumSubArray(a, low, mid);
		var right = findMaximumSubArray(a, mid + 1, high);
		var cross = findMaxCrossingSubArray(a, low, mid, high);
		if(left[2] >= right[2] && left[2] >= cross[2]){
			return left;
		} else if(right[2] >= left[2] && right[2] >= cross[2]){
			return right;
		} else {
			return cross;
		}
	}
}


« 上一篇下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。