lol
Actually, you could transfer exist knowledge into this new issue.
* Known: how to find max sum of subarray in a non-circle array.
New issue: how to find max sum of subarray in a circle array; which is equal to:
* find the max of the following two sums
* max sum of subarray in a non-circle array.
* sum of the whole array minus min sum of subarray in a non-circle array.
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using citer_t = std::vector<int>::const_iterator;
template <bool is_max>
bool findExtSumOFSubarray(citer_t first, citer_t last, int* res) {
constexpr auto update = [](int a, int b) { return is_max ? std::max(a, b) : std::min(a, b); };
if (0 == std::distance(first, last)) {
return false;
} else /* left blank intentionally */;
int tmp = *first;
*res = tmp;
for (++first; first != last; ++first) {
tmp = update(tmp + *first, *first);
*res = update(*res, tmp);
}
return true;
}
bool findMaxSumOFSubarray(citer_t first, citer_t last, int* res) {
return findExtSumOFSubarray<true>(first, last, res);
}
bool findMinSumOFSubarray(citer_t first, citer_t last, int* res) {
return findExtSumOFSubarray<false>(first, last, res);
}
bool findMaxSumOFSubarrayINCircle(citer_t first, citer_t last, int* res) {
if (std::all_of(first, last, [](int i){ return i < 0; })) {
return findMaxSumOFSubarray(first, last, res);
} else {
const int sum_of_source = std::accumulate(first, last, 0);
int max, min;
if (findMaxSumOFSubarray(first, last, &max) and findMinSumOFSubarray(first, last, &min)) {
*res = std::max(max, sum_of_source - min);
return true;
} else {
return false;
}
}
}
int main() {
const std::vector<int> source = {-1, -2, -3};
int res;
if (findMaxSumOFSubarrayINCircle(source.begin(), source.end(), &res)) {
std::cout << "Result: " << res << "." << std::endl; // Result: 31.
} else /* left blank intentionally */;
return 0;
}