По заданному бинарному дереву поиска и номеру найдите путь, данные узла которого добавлены в заданное число.

По заданному бинарному дереву поиска и числу найдите, существует ли путь от корня до листа, чтобы все числа на пути складывались в заданное число.

Я знаю, как сделать это рекурсивно. Но я предпочитаю итеративное решение.

Если мы будем выполнять итерацию от корня к листу каждый раз, будет перекрытие, потому что некоторые пути могут перекрываться.

Что если в дереве нет бинарного поиска?

Спасибо

3 ответа

По сути, эту проблему можно решить с помощью динамического программирования на дереве, чтобы избежать этих перекрывающихся путей.

Основная идея состоит в том, чтобы отслеживать возможные длины от каждого листа до данного узла в таблице f[node], Если мы реализуем его в 2-мерном логическом массиве, это что-то вроде f[node][len], который указывает, есть ли путь от листа к node с длиной, равной len, Мы также можем использовать vector<int> хранить значение в каждом f[node] вместо использования логического массива. Независимо от того, какое представление вы используете, способ расчета между различными f просты, в форме

f[node] is the union of f[node->left] + len_left[node] and f[node->right] + len_right[node].

Это случай двоичного дерева, но действительно легко распространить его на случаи не двоичного дерева.

Если что-то неясно, пожалуйста, не стесняйтесь комментировать.

Все, что вы можете делать рекурсивно, вы также можете делать итеративно. Однако у вас нет проблем с производительностью рекурсивного решения, тогда я бы оставил все как есть. Скорее всего, будет труднее кодировать / читать, если вы попытаетесь сделать это итеративно.

Однако, если вы настаиваете, вы можете превратить ваше рекурсивное решение в итеративное, используя стек. Каждый раз, когда вы делаете рекурсивный вызов, помещайте переменные состояния в текущем вызове функции в стек. Когда вы закончите с вызовом, всплывают переменные.

Для BST:

Node current,final = (initialize)
List nodesInPath;
nodesInPath.add(current);
while(current != final) {
    List childrenNodes = current.children;
    if(noChildren) noSolution;
    if(current < final) {
        //choose right child if there is one, otherwise no solution
        current = children[right];
    } else if(current > final){
        //choose left child if there is one, otherwise no solution
        current = children[left];         
    } 
    nodesInPath.add(current);
}
check sum in the nodesInPath

Однако для не BST вы должны применить решение с использованием динамического программирования, как предлагает derekhh, если вы не хотите вычислять одни и те же пути снова и снова. Я думаю, вы можете хранить общую длину между определенным обрабатываемым узлом и корневым узлом. Вы рассчитываете расстояния, когда расширяете их. Тогда вы бы подали заявку Breadth-first search чтобы не пересекать те же самые пути снова и использовать ранее вычисленные общие расстояния. Алгоритм, на мой взгляд, немного сложен, извините, но не хватает времени, чтобы написать его.

Другие вопросы по тегам