子数组问题

子数组的问题在面试中非常多,这里收集了一些子数组的问题,做一个总结:

1.连续子数组最大和
2.数组中最大连续递增子数组
3.数组中非连续最大递增子数组和
4.累加值为k的最长子数组,累加值不大于k的最长子数组


1. 连续子数组最大和

http://dsqiu.iteye.com/blog/1701494
连续子数组最大和,又叫最大子序列和或最大数组和,不过这里的序列好像有点不是很妥。

1.1问题描述

一个有N个元素的整型数组arr,有正有负,数组中连续一个或多个元素组成一个子数组,这个数组当然有很多子数组,求子数组之和的最大值。
子数组问题_第1张图片


2.

https://blog.csdn.net/dreamflyhua/article/details/21285247
这个题目有两种可能的

一种是求数组中最大的连续递增子序列,是连续递增的个数最大,而不是和。

方法一,通过辅助数组计数来完成:

子数组问题_第2张图片
子数组问题_第3张图片
子数组问题_第4张图片
子数组问题_第5张图片

第二种一种是求数组中连续递增子序列的最大和。

方法一:使用上面的双指针

这一种方法的思想其实和上面是一样的,去判断连续的递增数组的最大和,保存这个最大和,还是可以用双指针的办法,如果递增序列出现的断裂,这个时候记录断裂前的最大和,然后从断裂后重新开始计算。直到最后的指针到末尾了。
子数组问题_第6张图片
方法二:是否能采用dp的思想
dp[i] = dp[i-1]+a[i],while a[i]>a[i-1]>=0 && a[i]>a[i-1]<0;
dp[i] = a[i],while a[i] 子数组问题_第7张图片


3.最长递增子序列(不连续)

http://dsqiu.iteye.com/blog/1701494

3.1问题描述

设L=是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=,其中k1

3.2动态规划求解

从后向前分析,如果a[i]大于前面所有的数,则dp[i]在max{dp[j],j

设dp(i)表示L中以ai为末元素的最长递增子序列的长度。则有如下的递推方程: 这个递推方程的意思是,在求以ai为末元素的最长递增子序列时,找到所有序号在L前面且小于ai的元素aj,即j

给出动态规划的方程:

dp[i] = max(dp[j])+1  while j

子数组问题_第8张图片

3.3 排序+LCS求解

这个方法也是很直观的,对原数组a进行排序得到一个有序的数组b, 这样出现在数组a的最长递增子序列也一定是数组b的子序列。那么问题就转到求两个序列的最长公共子序列了,LCS显然可以用二维的动态规划来实现。
子数组问题_第9张图片
子数组问题_第10张图片

这种方法非常的精辟,用一个数组来记录当前长度为l的数组的最小元素,那么遍历所有的序列,最后看数组的长度为多少,就是最长的序列长度,其中插入数组元素覆盖的时候可以使用二分法,这样的时间复杂度降到了nlgn;
子数组问题_第11张图片
https://www.felix021.com/blog/read.php?1587


4.

https://blog.csdn.net/qq_26916359/article/details/76150822

问题描述1:给定一个数组,值全部是正数,请返回累加值为给定值 k 的最长连续子数组的长度。

子数组问题_第12张图片

子数组问题_第13张图片
这种双指针的方法虽然可以,但是存在一个问题就是这些数字必须是正数,这样才能保证根据与k的大小调整滑动窗口的大小。

问题描述2:给定一个数组,值可以为正数负数和0,请返回累加和为给定值 K 的最长子数组长度。

子数组问题_第14张图片

子数组问题_第15张图片
子数组问题_第16张图片
这个问题就是利用映射表来完成滑动窗口的值,通过映射表记录所有的和的值,然后看窗口为k的结果。

问题描述3:给定一个数组,值可以为正数负数和0,请返回累加和不大于k的最长子数组长度。

子数组问题_第17张图片
子数组问题_第18张图片

你可能感兴趣的:(算法,算法)