我最近接受了一家公司的采访,他们要求我编写一个算法,用于查找数组中元素数量最大的子序列。数组中的元素可以是负数。是否有O(n)解决方案?任何好的解决方案都非常感谢。查找数组中元素数量最大的子序列
回答
如果你想连续数字之和最大的则是这样的可能工作:
$cur = $max = 0;
foreach ($seq as $n)
{
$cur += $n;
if ($cur < 0) $cur = 0;
if ($cur > $max) $max = $cur;
}
这只是我的头顶部,但它似乎是正确的。 (忽略因为它假定0是空的,所有的负面套答案。)
编辑:
如果你也想的序列位置:
$cur = $max = 0;
$cur_i = $max_i = 0;
$max_j = 1;
foreach ($seq as $i => $n)
{
$cur += $n;
if ($cur > $max)
{
$max = $cur;
if ($cur_i != $max_i)
{
$max_i = $cur_i;
$max_j = $max_i + 1;
}
else
{
$max_j = $i + 1;
}
}
if ($cur < 0)
{
$cur = 0;
$cur_i = $i + 1;
}
}
var_dump(array_slice($seq, $max_i, $max_j - $max_i), $max);
有可能是一个更简洁的方式来做到这一点。同样,它也有相同的假设(至少有一个正整数)。而且,它只能找到第一个最大的序列。
编辑:更改为使用max_j
(独家)而不是max_len
。
这不是他正在寻找的。他要求一个具有最大总和的子序列。你给了他最大连续的子序列。和。在子序列中,数字不一定是连续的。 – 2012-03-09 01:24:02
@Kapil D,我的回答非常清楚地开始说出它正在回答的问题。他的面试官是在寻找什么?我们永远不会知道。显然,他正在寻找,他接受了。 (如果他真的想要一个最大总和的子序列,答案是微不足道的:删除所有负数。) – Matthew 2012-03-09 02:51:32
是的,我知道你写了它的序列号。可能是写这个问题的人不清楚。我喜欢你的解决最大序列问题。 – 2012-03-09 05:03:50
我假设你的意思是增长最长的子序列。
对此,没有O(n)
解决方案。
很天真的解决办法是在O(NlogN)
创建重复阵列,排序,然后找到排序后的数组和原始数组这需要O(N^2)
的LCS
。
还有一个类似于LCS
的直接基于DP的解决方案,它也需要O(N^2)
,你可以看到here。
但是,如果你的意思是最长的增加序列(连续)。这可以在O(N)
中完成。
如果您的意思是最长的子序列,请参阅codaddict的答案。
如果在另一方面,你的意思是寻找具有最大总和的子阵列(才有意义负值),则是一个优雅的,动态的编程风格的线性时间的解决方案:
良好的联系。看来我的答案只是该算法的一个实现。 – Matthew 2010-09-17 07:42:34
@ konforce:正好。当然,您还需要记录返回子数组本身的开始/结束位置。 +1。 – 2010-09-17 07:47:36
+1 ...找到这个算法是大多数介绍CS课程(CS 101或CS 102)的例行练习。 – 2010-09-17 08:23:09
C函数如下:
int largest(int arr[], int length)
{
int sum= arr[0];
int tempsum=0;
for(int i=0;i<length;i++){
tempsum+=arr[i];
if(tempsum>sum)
sum=tempsum;
if(tempsum<0)
tempsum=0;
}
return sum;
}
试试下面的代码:
#include <stdio.h>
int main(void) {
int arr[] = {-11,-2,3,-1,2,-9,-4,-5,-2, -3};
int cur = arr[0] >= 0? arr[0] : 0, max = arr[0];
int start = 0, end = 0;
int i,j = cur == 0 ? 1 : 0;
printf("Cur\tMax\tStart\tEnd\n");
printf("%d\t%d\t%d\t%d\n",cur,max,start,end);
for (i = 1; i < 10; i++) {
cur += arr[i];
if (cur > max) {
max = cur;
end = i;
if (j > start) start = j;
}
if (cur < 0) {
cur = 0;
j = i+1;
}
printf("%d\t%d\t%d\t%d\n",cur,max,start,end);
}
getchar();
}
void longsub(int a[], int len) {
int localsum = INT_MIN;
int globalsum = INT_MIN;
int startindex = 0,i=0;
int stopindex = 0;
int localstart = 0;
for (i=0; i < len; i++) {
if (localsum + a[i] < a[i]) {
localsum = a[i];
localstart = i;
}
else {
localsum += a[i];
}
if (localsum > globalsum) {
startindex = localstart;
globalsum = localsum;
stopindex = i;
}
}
printf ("The begin and end indices are %d -> %d (%d).\n",startindex, stopindex, globalsum);
}
这个问题是可以解决两种不同的方式。
第一种方法是有两个变量sum
和MaxSum
。
我们将不断增加值的总和,并将与MaxSum比较,如果总和值大于MaxSum更大 - 将总和值分配给MaxSum
如果在处理金额低于0的值,我们将重新设置金额,并开始向下一个索引添加新号码。 对于上述溶液中的示例代码被提供如下:
private static void FindMaxSum(int[] array) { int sum = 0; int MaxSum = 0; for (int i = 0; i < array.Length; i++) { sum += array[i]; if (sum > MaxSum) { MaxSum = sum; } else if (sum < 0) { sum = 0; } } Console.WriteLine("Maximum sum is: " + MaxSum); }
来解决这个问题的第二种方法是,我们将通过每阵列中的每个元素。我们将有和sum和MaxSum相同的2个变量。
首先,我们将和下一个数组元素和总和本身进行比较。谁更伟大 - 该值将被存储在sum变量中。
接下来我们将比较sum和MaxSum的值以及谁有更大的价值 - 我们会将该值保存在MaxSum变量中。 示例代码如下所述:
private static void FindMaxSum(int[] array) { int sum = array[0], Maxsum = array[0]; for (int i = 1; i < array.Length; i++) { sum = Max(sum + array[i], array[i]); Maxsum = Max(sum, Maxsum); } Console.WriteLine("Maximum sum is: " + Maxsum); } private static int Max(int a, int b) { return a > b ? a : b; }
如果你问的是一个连续的子序列,其总和是最大的,我已经找到4个交易算法迄今: -
Brute-force:使用嵌套循环查找所有可能的总和,如果发现总和大于先前设置的maxSum设置值,则继续更新maxSum。时间复杂度为O(n^2)
动态规划解决方案:这是一个非常优雅的解决方案,我在计算器上自己发现 - https://stackoverflow.com/a/8649869/2461567v - 时间复杂度:O(N), 空间复杂度:O(N )
DP没有记忆 - Kadane算法 - https://en.wikipedia.org/wiki/Maximum_subarray_problem - 时间复杂度:O(N),空间复杂度:O(1)
分而治之解决方案 - http://eecs.wsu.edu/~nroy/courses/CptS223/notes/MaxSubsequenceSum.pdf 时间复杂度:O(nlgn)
- 1. 查找数组中相同元素的最大序列
- 2. 三维数组中特定元素序列的最大数量
- 3. 在C中查找递增顺序的最大子数组元素的总和?
- 4. 查找具有最大和最小元素数的数组
- 5. 如何在java中查找最大序列和的子数组?
- 6. 查找数组中的最小元素。
- 7. 查找阵列中最大的元素
- 8. 查找数组元素的数量
- 9. 查找包含多个数组中最大/最小值元素的数组?
- 10. 在swift中查找二维数组中的最大元素
- 11. 如何查找数组中大于其后所有元素的元素数量?
- 12. 如何查找数组的最小和最大元素?
- 13. 查找数组中元素的最大和
- 14. 使用foreach循环查找数组中最大的元素
- 15. 查找n个不同数组中常见的最大元素?
- 16. 使用JavaScript在数组中查找最大的元素
- 17. 如何从排序的数组中找到最大的元素?
- 18. 找到列表中最大数量的类似元素
- 19. 在电子表格中查找离散组的最大数量
- 20. 在动态数组的前N个元素中查找最大元素
- 21. Buuble排序来查找数组中的五个最小元素
- 22. 查找未排序数组中的第k个最小元素
- 23. 查找数组中的最大分数
- 24. 数组中等元素的最大序列
- 25. 在排序中查找数组中第n个最小元素?
- 26. 查找数组中的多数元素
- 27. 查找数组元素的最大区别
- 28. 一次查找数组12个元素的最大值
- 29. 递归地查找数组的最大元素
- 30. C++查找数组的最大元素仅使用指针
你是说**最长的子序列吗?也是最长的吗? – codaddict 2010-09-17 06:59:52
你是什么意思的“最大subquance”? - 哦好的。你可能的意思是:找到元素总和最大的子序列。 – sellibitze 2010-09-17 07:05:39
你是指数字的最长序列,这些数字的总和在数组中最大? – jsshah 2010-09-17 07:09:46