leetcode98:验证二叉搜索树

题目链接

leetcode

题目描述

给一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效二叉搜索树定义如下:

  • 节点的左子树只包含 小于 当前节点的数。
  • 节点的右子树只包含 大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

C++ 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;

// 二叉树结点的定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

const int NULL_NODE = 0;

// 辅助函数:创建二叉树
TreeNode* createTree(const vector<int>& nums) {
if (nums.empty()) return nullptr;

TreeNode* root = new TreeNode(nums[0]);
queue<TreeNode*> queue;
queue.push(root);
int i = 1;
while (!queue.empty() && i < nums.size()) {
TreeNode* node = queue.front(); queue.pop();
if (nums[i] != NULL_NODE) {
node->left = new TreeNode(nums[i]);
queue.push(node->left);
}
i++;
if (i < nums.size() && nums[i] != NULL_NODE) {
node->right = new TreeNode(nums[i]);
queue.push(node->right);
}
i++;
}

return root;
}

// 辅助函数:层序遍历打印二叉树
void levelOrderTraversal(TreeNode* root) {
if (root == nullptr) return;

queue<TreeNode*> queue;
queue.push(root);
while (!queue.empty()) {
TreeNode* node = queue.front(); queue.pop();
cout << node->val << " ";
if (node->left != nullptr) queue.push(node->left);
if (node->right != nullptr) queue.push(node->right);
}
cout << endl;
}

// 辅助函数:释放二叉树
void deleteTree(TreeNode* root) {
if (root == nullptr) return;
deleteTree(root->left);
deleteTree(root->right);
delete root;
}

/*
深度优先遍历,递归实现

对于每个结点,传递其允许的最小值和最大值范围。
遍历它的左子树,判断左子树是否有效,判断左子树的最大值是否小于当前结点的值;
遍历它的右子树,判断右子树是否有效,同时判断右子树的最小值是否大于当前结点的值。
若条件均满足,则说明以当前结点为根的子树是一棵二叉搜索树,返回 true。

时间复杂度:O(n)
其中 n 为二叉树结点的个数,树中每个结点被遍历一次。
*/
class Solution {
public:
bool isValidBST(TreeNode* root) {
return dfs(root, nullptr, nullptr);
}

bool dfs(TreeNode* root, TreeNode* minNode, TreeNode* maxNode) {
if (root == nullptr) {
return true;
}
if (minNode && root->val <= minNode->val) {
return false;
}
if (maxNode && root->val >= maxNode->val) {
return false;
}

// 递归地检查左子树和右子树
return dfs(root->left, minNode, root)
&& dfs(root->right, root, maxNode);
}
};

// 辅助函数:打印数组
void printArray(const vector<int>& nums) {
cout << "[";
for (size_t i = 0; i < nums.size(); i++) {
cout << nums[i];
if (i != nums.size() - 1) cout << ",";
}
cout << "]" << endl;
}

int main() {
Solution solution;
vector<vector<int>> root_cases = {
{2,1,3},
{5,1,4,NULL_NODE,NULL_NODE,3,6}
};

for (const auto& nums : root_cases) {
cout << "Input: ";
printArray(nums);

// 创建二叉树
TreeNode* root = createTree(nums);
// 中序遍历
bool result = solution.isValidBST(root);
cout << "Output: " << (result ? "true" : "false") << endl;

// 释放内存
deleteTree(root);
}

return 0;
}

leetcode98:验证二叉搜索树
https://lcf163.github.io/2024/03/10/leetcode98:验证二叉搜索树/
作者
乘风的小站
发布于
2024年3月10日
许可协议