leetcode 53&152

Maximum Subarray & Maximum Product Subarray

这两个题目比较相似,我们可以先来看一下两个题目:
在这里插入图片描述
在这里插入图片描述
这两个题目都需要求得子数组相应的最大值,第一个是子数组的和,第二个是子数组的乘积。这个问题可以延伸到类似于这样求子数组的问题中去。
该类问题我采用的是动态规划的算法来解决。

53

这道题中,如需求得 到原数组第i个元素为止,能够得到的子数组最大和,那么就只需通过加和 到第i-1个元素为止的子数组最大和加上第i个元素,或者是第i个元素本身。即:

f(i) = max(f(i-1) + nums[i], nums[i])
其中f(i)表示原数组到第i个元素为止,能够得到的子数组最大和,nums[i]表示原数组的第i个元素。如此我们就得到了这样的子问题求解方式,就可以运用递归或动态规划方式来解决。运用递归的方法在这里就不展示代码了,这里只写一下使用一个数组来保存f(i),能够方便f(i+1)来调用的方法:
int maxSubArray(int *nums, int numsSize) {
	int *temp = (int*)malloc(sizeof(int)*numsSize);
	temp[0] = nums[0];
	for (int i = 1; i < numsSize; i++) {
		if (temp[i - 1] <= 0) temp[i] = nums[i];
		else temp[i] = temp[i - 1] + nums[i];
	}
	int max = temp[0];
	for (int i = 1; i < numsSize; i++) {
		if (temp[i] > max)	max = temp[i];
	}
	return max;
}

这个代码非常简洁,其核心思想就是用temp数组来存储f(i),使得temp数组中存储的是其对应下标的最大子数组和,而迭代的核心则是,在计算temp[i]时,若发现temp[i-1]小于等于0,则直接拷贝nums[i]到temp[i]中;若大于0,则将nums[i] + temp[i-1]加入到temp[i]中,并以次法迭代。
对temp数组进行更新后,遍历数组,找出最大值,输出。

152

这个题我们也可以参考前面的思想,但是需要做一些改动。在求和问题中,我们可以通过前一个的状态来做出判定,但是在乘积问题中,有可能出现,负负得正的情况,会使得原来比较小的值,直接因为符号的转换而变成较大的值。因此在这个问题中,我们不仅要记录最大的乘积,而且还要记录最小的乘积(这些乘积往往为负值或者0),最后,为了省去最后一轮的遍历求最大值,我们也可以准备一个结果数组,具体的代码如下:

int maxProduct(int* nums, int numsSize) {
	int *tempMax = (int*)malloc(sizeof(int)*numsSize);
	int *tempMin = (int*)malloc(sizeof(int)*numsSize);
	int max;
	tempMax[0] = tempMin[0] = max = nums[0];
	for (int i = 1; i < numsSize; i++) {
		int tempMaxValue = nums[i] * tempMax[i - 1];
		int tempMinValue = nums[i] * tempMin[i - 1];
		tempMax[i] = Max(tempMaxValue, tempMinValue, nums[i]);
		tempMin[i] = Min(tempMaxValue, tempMinValue, nums[i]);
		if (tempMax[i] > max) max = tempMax[i];
	}
	return max;
}

其中Max和Min是表示求三个值中的最大值和最小值,在这里不给出具体代码了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值