在数组这儿的题中,发现有很多很多题都跟子数组有关,现总结一下子数组相关题型。
求最大/小子数组和/积
这种题一般用DP解决比较方便,dp数组中保存以i为结尾的子数组的和/积
求最大子数组和
leetcode题目地址
很基础的DP
public int MaxSubArray(int[] nums)
{
if (nums.Length == 0) return 0;
var dp = nums[0];
var max = dp;
for (var i = 1; i < nums.Length; i++)
{
dp = Math.Max(nums[i], dp + nums[i]);
max = Math.Max(dp, max);
}
return max;
}
求最大子数组乘积
public int MaxProduct(int[] nums)
{
if (nums == null || nums.Length == 0) return 0;
var dpPos = Math.Max(nums[0], 0);//直接用变量存dp阶段值
var dpNeg = Math.Min(nums[0], 0);
var max = nums[0];//因为题目要求至少包含一个数,所以此处应该赋值为nums[0]
for (var i = 1; i < nums.Length; i++)
{
if (nums[i] >= 0)
{
dpPos = Math.Max(dpPos * nums[i], nums[i]);
dpNeg = Math.Min(dpNeg * nums[i], nums[i]);
}
else
{
var temp = dpPos;//注意此处,因为直接用变量存上一个状态,下一句会改掉本来的dpPos值,会影响到下下一句,所以先把dpPos原本的值拎出来
dpPos = Math.Max(dpNeg * nums[i], nums[i]);
dpNeg = Math.Min(temp * nums[i], nums[i]);
}
max = Math.Max(max, dpPos);
}
return max;
}
用滑动窗口
见另一篇文章,滑动窗口
求和为k的子数组
这道题是从两数之和衍生出来的,见另一篇文章。