Во время телефонного интервью меня попросили внедрить обход в порядке бинарного дерева поиска, используя Iterator & Stack ( не рекурсивно ).Мне не разрешили использовать родительский указатель.
Это начальный код, который мне дали.
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}};
class BTIterator
{
public:
BTIterator(TreeNode *root){
};
TreeNode* next() {
}
bool hasNext() {
}
};
Функция тестирования:
void TestFunc(TreeNode *root) {
BTIterator bti(root);
while(bti->hasNext()) {
cout << bti->next()->val << " ";
}}
Я был специальнопопросили реализовать BTIterator
, next
, hasNext
в приведенном выше коде.
Так я и сделал.Последующие вопросы были каковы время и пространство сложности.Поэтому я ответил, что время O (N), пространство O (N).Однако интервьюер сказал: «Вы можете уменьшить сложность пространства до O (log N)».Я спросил его, как, и он сказал: «Нам нужно только хранить родителей».(Я мог бы услышать его неправильно. У него был очень сильный акцент.) Моя реализация хранила все узлы, которые оставили детей.Я просто воспринял его ответ как должное.
Однако после интервью, я думаю, даже если нам нужно только сохранить родителей (не листовой узел), это все равно O (N).Это точный O (N / 2), но это все еще O (N).Я считаю, любой узел, который оставил дочерние элементы , должен храниться в стеке.Как не делать?
Единственный раз, когда можно достичь пробела O (logN), это когда двоичное дерево имеет только одну ветвь, которая продолжает работать (не сбалансированное дерево с полными листьями.)
Что мне здесь не хватает?Если кто-нибудь может объяснить, как сложность пространства с помощью итератора может быть уменьшена до O (log N), я буду очень признателен!