我正在编写一个函数,该函数除了数组的长度外,还包含指向动态分配的数组的指针。我试图找到它的连续子数组的第二个最小的和。
我一直在编写代码以计算数组中的第二个最小值,并且还编写了一段代码,用于计算所有连续子数组的和。我希望我能够将这两个部分“合并”在一起,以获得我想要的最终结果,但是我陷入了困境。我真的很感谢您的帮助。 谢谢。
#include <iostream>
using namespace std;
int secondSmallestSum(int *numbers,int length)
{
//Below shows the sum of all contiguous sub arrays.
for(i = 0; i<= length; ++i)
{
int sum = 0;
for(int j = i; j <= length; ++j)
{
sum+=*(numbers+j);
}
}
//Below calculates the second smallest element in an array
int smallest, secondsmallest;
if (*numbers < *(numbers+1))
{
smallest = *numbers;
secondsmallest = *(numbers+1) ;
}
else {
smallest = *(numbers+1) ;
secondsmallest = *(numbers) ;
}
for (i = 2; i < length; i++) {
if (*(numbers+i) < smallest)
{
secondsmallest = smallest;
smallest = *(numbers+i);
}
else if (*(numbers+i) < secondsmallest)
{
secondsmallest = *(numbers+i);
}
}
}
答案 0 :(得分:0)
您可以执行类似的操作(当然,您需要添加范围检查)。
#include <iostream>
#include <vector>
#include <algorithm>
int main(int argc, char** argv) {
std::vector<int> v{3, 1, 4, 5, 6, 2};
std::nth_element(v.begin(), v.begin() + 1, v.end());
std::cout << "The second smallest element is " << v[1] << "\n";
}
注意:使用nth_element会更改向量中元素的顺序。
答案 1 :(得分:0)
如果我理解您有误,请纠正我,
通过查看“ 找到其连续子数组的第二个最小和 ”和您发布的代码,我假设您的逻辑是
实际上,有一种众所周知的算法,即 Kadane算法 ,其用途相似(只有Kadane的算法找到的是最小的,而不是第二个最小的)。您可能需要在Google上查找更多内容。
回到您的问题,我相信以下代码可以满足您的需求。该代码是Kadane算法的一种变体。
#include <climits> // for INT_MAX
int findSecondMinOfContiguousSubarray(int arr[], int n)
{
// to store the minimum value that is ending
// up to the current index
int min_ending_here = INT_MAX;
int min = INT_MAX; // absolute min
int min_second = INT_MAX - 1; // second min <- this is what you want
// traverse the array elements
for (int i = 0; i<n/*it is <, not <=*/; i++)
{
// if min_ending_here > 0, then it could not possibly
// contribute to the minimum sum further
if (min_ending_here > 0)
min_ending_here = arr[i];
// else add the value arr[i] to min_ending_here
else
min_ending_here += arr[i];
// update min and min_second
if (min_second > min_ending_here) {
if (min > min_ending_here) {
min_second = min;
min = min_ending_here;
}
else {
min_second = min_ending_here;
}
}
}
return min_second;
}
顺便说一句,我认为您的代码(//下面的代码显示了所有连续子数组的总和。)找不到所有连续子数组。
例如arr = {1,2,3},您的代码仅将{1,2,3},{2,3}和{3}视为连续的子数组,而实际上{1,2}还应该考虑。
答案 2 :(得分:0)
蛮力o(n^2)
的复杂度(采用C ++而非C风格):
template<typename Container, typename Func>
void forEachSubrange(Container &container, Func &&f)
{
for (auto subBegin = container.begin(); subBegin != container.end(); ++subBegin)
{
auto subEnd = subBegin;
do {
++subEnd;
f(subBegin, subEnd);
} while (subEnd != container.end());
}
}
int secondSmallestSubrangeSum(const std::vector<int> &a)
{
int firstSum = 0; // empty sub range has zero sum
int secondSum = 0;
forEachSubrange(a, [&firstSum, &secondSum](auto b, auto e) {
auto sum = std::accumulate(b, e, 0);
if (sum < firstSum) {
secondSum = firstSum;
firstSum = sum;
} else if (sum < secondSum) {
secondSum = sum;
}
});
return secondSum;
}
我确定可以实现o(n)
。
https://wandbox.org/permlink/9cplKBIpfZBPpZ27 或更健谈的https://wandbox.org/permlink/X21TdH6xtbMLpV19