C++ LeetCode 53:最大子序和

前言
这道题目有三种解法:

  1. 暴力解法:求出所有的子序列和,找到最大的那一个。时间复杂度为O(n^2)
  2. 分治法:将所求序列一分为二,分别求左、右子序列的最大和,然后再求中间跨界的最大和,最后比较三者的大小,找到最大的那一个。时间复杂度为O(nlog(n))
  3. 在线处理:顺序遍历序列求和,将和为负的所有值舍弃,即置零,最后求出和的最大值。时间复杂度为O(n)

题目描述
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

实现方法
一、暴力求解

int MaxSubseqSum1(int a[], int n) {
	int CurrentSum, MaxSum = 0;
	for (int i = 0; i < n; i++) {
		CurrentSum = 0;
		for (int j = i; j < n; j++) {
			CurrentSum += a[j];
			if (CurrentSum > MaxSum)
				MaxSum = CurrentSum;
		}
	}
	return MaxSum;
}

二、分治法

//3个数比大小,返回最大值
int MaxNum3(int a, int b, int c) {
	return a > b ? a > c ? a : c : b > c ? b : c;
}

//二分法:递归。 O(nlog(n))
int BinaryMaxSubSum(int list[], int left, int right) {
	int MaxLeftSum, MaxRightSum;
	int MaxBoardSum, MaxLeftBoardSum = 0, MaxRightBoardSum = 0;
	int i, center;

	//判断递归终止条件
	if (left == right) {
		if (list[left] > 0)
			return list[left];
		return 0;
	}

	//进行分治,求得左序列和最大值、右序列和最大值
	center = (left + right) / 2;
	MaxLeftSum = BinaryMaxSubSum(list, left, center);
	MaxRightSum = BinaryMaxSubSum(list, center + 1, right);
	
	//求中间跨界的和最大值
	int LeftBoardSum = 0, RightBoardSum = 0;
	for (i = center; i >= left; i--) {
		LeftBoardSum += list[i];
		if (LeftBoardSum > MaxLeftBoardSum) {
			MaxLeftBoardSum = LeftBoardSum;
		}
	}
	for (i = center + 1; i <= right; i++) {
		RightBoardSum += list[i];
		if (RightBoardSum > MaxRightBoardSum) {
			MaxRightBoardSum = RightBoardSum;
		}
	}
	MaxBoardSum = MaxLeftBoardSum + MaxRightBoardSum;

	//比较三者的大小,返回最大值
	return MaxNum3(MaxBoardSum, MaxLeftSum, MaxRightSum);
}

int MaxSubseqSum2(int a[], int n) {
	return BinaryMaxSubSum(list, 0, n - 1);
}

三、在线处理

int MaxSubseqSum3(int a[], int n) {
	int CurrentSum = 0, MaxSum = a[0];
	for (int i = 0; i < n; i++) {
		CurrentSum += a[i];
		if (CurrentSum > MaxSum) {
			MaxSum = CurrentSum;
		}
		if (CurrentSum < 0) {
			CurrentSum = 0;		//如果子序列和为负,则置零
		}
	}
	return MaxSum;
}

总结
比较上面的三种方法,第三种方法最好。但是分治法的思想也很精妙,需要掌握。

你可能感兴趣的:(C++LeetCode)