给出了一个由N个整数组成的非空零索引数组。一对整数(P,Q),如0≤ P
编写一个函数:
int解(int A[],int N);
给定一个由N个整数组成的非空零索引数组a,它将以最小的平均值返回切片的起始位置。如果有多个切片具有最小平均值,则应返回该切片的最小起始位置。
假定:
N是[2..100000]范围内的整数;数组A的每个元素都是范围内的整数[−10,000..10,000]. 复杂性:
预期最坏情况时间复杂度为O(N);预计最坏情况下的空间复杂度为O(N),超出了输入存储空间(不计算输入参数所需的存储空间)。
你能只发布顺序N的解决方案吗?
#include <assert.h>
struct Slice { unsigned P, Q; };
struct Slice MinSlice( int A[], unsigned N ) {
assert( N>=2 );
// find min slice of length 2
unsigned P = 0;
double min_sum = A[P] + A[P+1];
for (unsigned i = 1; i < N-1; ++i)
if ( min_sum > A[i] +A[i+1] ) {
P = i;
min_sum = A[P] + A[P+1];
}
unsigned Q = P+1;
double min_avg = min_sum / 2;
//extend the min slice if the avg can be reduced.
//(in the direction that most reduces the avg)
for (;;) {
if ( P > 0 && ( Q >= N-1 || A[P-1] <= A[Q+1] ) ) {
//reducing P might give the best reduction in avg
double new_sum = A[P-1] + min_sum;
double new_avg = new_sum / (Q - P + 2);
if ( min_avg < new_avg )
break;
min_sum = new_sum;
min_avg = new_avg;
--P;
} else if ( Q < N-1 && ( P <= 0 || A[P-1] >= A[Q+1] ) ) {
//increasing Q might give the best reduction in avg
double new_sum = min_sum + A[Q+1];
double new_avg = new_sum / (Q - P + 2);
if ( min_avg < new_avg )
break;
min_sum = new_sum;
min_avg = new_avg;
++Q;
} else
break;
}
struct Slice slice = { .P = P, .Q= Q };
return slice;
}
我想你是对的,我能做的最好的是一个O(N2)解决方案(这是Python的):
from random import randint
N = 1000
A = [randint(-10000, 10000) for _ in xrange(N)]
def solution(A, N):
min_avg = 10001
for p in xrange(N):
s = A[p]
for q in xrange(1,N-p):
s += A[p+q]
a = s / (q+1.)
if a < min_avg:
min_avg = a
pos = (p, q+1)
return pos
print solution(A, N)
然而,较大切片的平均值趋向于原始范围的平均值(中间值)。在这种情况下,平均值为零,介于-10000和10000之间。大多数情况下,最小的平均值是两个值的一部分,但有时可能是三个值的一部分,很少可能是更多的值。所以我认为我之前的答案在大多数情况下都适用(
如果A
只有正数,你可以不受惩罚:
pos = 0
min_avg = A[0] + A[1]
for (i=2; i<N; i++)
m = A[i-1] + A[i]
if (m < min_avg)
min_avg = m
pos = i-1
return pos
这只是取两个数的一个切片的平均值,因为较大切片的平均值不能小于较小切片的最小值。
如果A有负数,可以先向上调整所有值:
offset = min(A)
for (i=0; i<N; i++)
A[i] -= offset
结合前面的算法:
offset = min(A) * 2 (because we're adding two numbers below)
pos = 0
min_avg = A[0] + A[1] - offset
for (i=2; i<N; i++)
m = A[i-1] + A[i] - offset
if (m < min_avg)
min_avg = m
pos = i-1
return pos
我在尝试解决求MaxDoubleSliceSum值的问题。简单地说,它是任何切片的最大和减去该切片中的一个元素(您必须删除一个元素,并且第一个和最后一个元素也被排除在外)。因此,从技术上讲,数组的第一个和最后一个元素不能包含在任何片和中。 以下是完整描述: 给出了一个非空的零索引数组由整数组成。三元组,使得 使得: 包含以下双切片示例: 双切片,总和 在给定由< code>N个整数组成的非空零索引
我正试图找到一个子阵列最小切片的余数问题的解决方案,并且我已经设计了一个使用Kadane算法的修改版本的解决方案。我目前已经拿到了90/100,并且设法通过了O(n)的几乎所有考试。但是我好像过不了“medium_range,increasing,decreasing(legth = ~ 100)and small functional,got 5 expected 3”,我也不知道为什么。这可能
问题内容: 转到“切片”问题,请检查以下内容,并在我遗漏某些东西时发表评论。 输出: 以上是合理的。 输出: 这是否也应该使数组摆脱s = s [:2]的恐慌? 问题答案: Go中的Subslicing可让您在切片末尾进行切片,只要它仍在底层阵列的容量范围内即可。您不能 在 该切片的开始 之前 进行切片,但是只要不超过最后分配的索引,就可以在该切片之后进行切片。 例如,然后工作,但随后会出现恐慌,
我的看法是: 改变符号并在其中找到最大和,与我们计算最大和子数组的方法相同。改变数组中元素的符号使其处于初始状态。 如果algo有任何问题,请帮助我更正。 拐角情况:我知道如果所有元素都是正的就会有问题,我们可以通过做一些预处理来处理这种情况,即如果所有元素都是+Ve,就遍历数组,而不仅仅是从数组返回最小值。 上面提到的算法将工作,并得到DasBlinkenlight的良好支持(解释)。
问题内容: 如何确定切片中存在的元素的位置? 我需要以下内容: 问题答案: 抱歉,没有通用库函数可以执行此操作。Go并没有直接的方法来编写可以在任何片段上运行的函数。 您的函数可以运行,尽管如果使用编写它会更好一些。 如果碰巧有一个字节片,则为bytes.IndexByte。
问题内容: 我很好奇拆包切片并将其作为参数发送给可变参数函数。 假设我们有一个带有可变参数的函数: 如果我们不想传入一个接口,它就可以工作,那么我们是否拆包都没关系: 如果我们有一片片的话,那会很棘手。在这里,编译器不允许我们传递解压版本: 错误提示: 在解包参数中不能将sliceOfSlices(类型[] [] interface {})用作类型[] interface {} 我不知道为什么会这