Вы можете решить эту проблему в O(NlogN)
или O(N)
(в среднем).
Сначала необходимо выполнить предварительную обработку, сохранив все суммы справа налево в данныхструктура, в частности сбалансированное двоичное дерево поиска (например, Красно-черное дерево , AVL-дерево, Splay Tree и т. д., если вы можете использовать stdlib
, просто используйте std::multiset
) или HashTable (в stdlib
это std::unordered_multiset
):
void preProcessing(dataStructure & ds, int * arr, int n){
int sum = 0;
int * toDelete = (int) malloc(n)
for(int i = n-1; i >= 0; --i){
sum += arr[i];
toDelete[i] = sum; // Save items to delete later.
tree.insert(sum);
}
Таким образом, чтобы решить проблему, вам просто нужно пройти массив один раз:
// It considers that the deleted subarray could be empty
bool Solve(dataStructure & ds, int * arr, int n, int * toDelete){
int sum = 0;
bool solved = false; // true if a solution is found
for(int i = 0 ; i < n; ++i){
ds.erase(toDelete[i]); // deletes the actual sum up to i-th element from data structure, as it couldn't be part of the solution.
// It costs O(logN)(BBST) or O(1)(Hashtable)
sum += arr[i];
if(ds.find(sum)){// If sum is in ds, then there's a leftsum == rightsum
// It costs O(logN)(BBST) or O(1)(HashTable)
solved = true;
break;
}
}
return solved;
}
Затем, если вы используетеBBST (сбалансированное бинарное дерево поиска) ваше решение будет O(NlogN)
, но если вы используете HashTable, ваше решение будет в среднем O(N)
.Я бы этого не реализовал, так что, возможно, есть ошибка, но я пытаюсь объяснить основную идею.