Задача заключается в том, чтобы найти верхний вид бинарного дерева.
Я пытался решить эту задачу без использования карты или очереди, но мой код не проходит большинство тестов. Я не понимаю, почему.
Сначала я нашел левый вид, затем добавил корень и затем добавил правый вид.
Я просто использовал целочисленную переменную x, чтобы отслеживать координату x, и убедился, что в ans попадает только самый верхний элемент для этой x.
`void leftTop(TreeNode<int> *root , vector<int> &topView){
if(root->left==NULL) return;
TreeNode<int> *node = root;
int x=0;
int xmin=0;
node = node->left;
x--;
while(node){
if(x<xmin) topView.push_back(node->data);
xmin=min(xmin,x);
if(node->left){
node = node->left;
x--;
}
else if(node->right){
node = node->right;
x++;
}
else {
reverse(topView.begin(),topView.end());
return;
}
}
reverse(topView.begin(),topView.end());
}
void rightTop(TreeNode<int> *root , vector<int> &topView){
if(root->right==NULL) return;
TreeNode<int> *node = root;
int x=0;
int xmax=0;
node = node->right;
x++;
while(node){
if(x>xmax) topView.push_back(node->data);
xmax=max(xmax,x);
if(node->right){
node = node->right;
x++;
}
else if(node->left){
node = node->left;
x--;
}
else return;
}
}
vector<int> getTopView(TreeNode<int> *root)
{
vector<int> topView;
leftTop(root,topView);
topView.push_back(root->data);
rightTop(root,topView);
return topView;
}
`
Ответ
Код, представленный для нахождения верхнего вида бинарного дерева, имеет несколько проблем, из-за которых он не работает должным образом. Ниже я объясню основные причины, почему этот код не правильный, и предложу более подходящий способ решения задачи.
Проблемы кода:
-
Неполное отслеживание узлов:
Код, использующий функцииleftTop
иrightTop
, не учитывает узлы на одном уровне, поскольку он не проверяет, существует ли узел перед его добавлением в результирующий векторtopView
. Если узел на одном уровне уже был добавлен (например, при добавлении левого узла), последующий узел (какой-то правый) на том же уровне может не добавиться, что нарушает правильность результата. -
Логика обхода:
Логика обхода дерева не охватывает все возможные случаи, когда узлы могут находиться на одной высоте, и допустимо использовать только один, при этом векторtopView
может не корректно отображать верхний вид дерева. - Отсутствие
map
илиqueue
:
Обычно для решения подобных задач используют структуру данных, такую какmap
, для хранения узлов в соответствии с их горизонтальными координатами. Код, который не использует такие структуры, сложно поддерживать и выводить правильный результат.
Рекомендованное решение:
Вместо использования подхода, представленного в вопросе, вы можете воспользоваться подходом с использованием map
и queue
. Такой способ гарантирует, что вы охватываете все узлы на одном уровне и сохраняете корректные горизонтальные координаты. Ниже приведен исправленный код:
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
struct TreeNode {
int data;
TreeNode* left;
TreeNode* right;
TreeNode(int val) : data(val), left(NULL), right(NULL) {}
};
vector<int> getTopView(TreeNode* root) {
vector<int> topView;
if (root == NULL) return topView;
// Пара (узел, горизонтальная координата)
map<int, int> topNodes;
queue<pair<TreeNode*, int>> q;
// Начинаем с корня (координата 0)
q.push({root, 0});
while (!q.empty()) {
auto current = q.front();
q.pop();
TreeNode* node = current.first;
int hd = current.second; // горизонтальная координата
// Если еще нет узла на данной координате, добавляем его
if (topNodes.find(hd) == topNodes.end()) {
topNodes[hd] = node->data;
}
if (node->left) {
q.push({node->left, hd - 1}); // левая координата на один меньше
}
if (node->right) {
q.push({node->right, hd + 1}); // правая координата на один больше
}
}
// Сортируем по горизонтальным координатам и заполняем вывод
for (auto& pair : topNodes) {
topView.push_back(pair.second);
}
return topView;
}
Объяснение решения:
- Мы используем
queue
для выполнения обхода в ширину (BFS), который позволяет нам обойти дерево по уровням. map
используется для отслеживания первого узла, который мы встречаем на каждой горизонтальной координате.- После обхода мы просто проходим по
map
и заполняем результирующий вектор узлов, сохраняя их в порядке горизонтальных координат.
Таким образом, это решение гарантирует, что мы правильно получим верхний вид бинарного дерева.