验证二叉搜索树

link:98. 验证二叉搜索树 - 力扣(LeetCode)

思路分析

搞清二叉搜索树的定义即可.(根节点的左子树比根节点小,右子树比根节点大且每个子树都满足)
image-20241114113444728

但其实上述思路是是不对, 跑一下代码发现测试样例值通过了一部分.那是哪里出问题了?(烧烤)
比较的应该是左子树所有节点小于中间节点,右子树所有节点大于中间节点.
查资料发现二叉搜索树也可以为空

迭代
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
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
return validBST(Long.MIN_VALUE, Long.MAX_VALUE, root);
}
boolean validBST(long lower, long upper, TreeNode root) {
if (root == null) {
return true;
}
if (root.val <= lower || root.val >= upper) {
return false;
}
return validBST(lower, root.val, root.left) && validBST(root.val, upper, root.right);
}
}
中序遍历

采用pre指针遍历对比记录前一个节点内容,进行中序遍历比较.

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
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
TreeNode pre = null;
public boolean isValidBST(TreeNode root) {
if(root == null) {
return true;
}
boolean left = isValidBST(root.left);
//确保至少以及遍历过一个节点
if(pre != null && pre.val >= root.val) {
return false;
}
//更新节点
pre = root;
boolean right = isValidBST(root.right);
return left && right;
}
}

二叉搜索树的最小绝队差

link:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

思路分析

和上一题一样,用一个指针记录遍历比较再用一个大数值记录结果即可.【注意取值】

中序遍历
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
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
TreeNode pre = null;
int result = Integer.MAX_VALUE;
public int getMinimumDifference(TreeNode root) {
if(root == null) {
return 0;
}
//左
getMinimumDifference(root.left);
//判断
if(pre != null) {
int tmp = root.val - pre.val;
if(tmp < result) {
result = tmp;
}
}
//更新节点
pre = root;
//右
getMinimumDifference(root.right);
return result;
}
}

二叉搜索树中的众数

link:501. 二叉搜索树中的众数 - 力扣(LeetCode)

思路分析

最直接就是直接遍历搜索,使用Map比较记录.但是这样就失去了搜索二叉树的意义.
所以我们还是选择中序遍历的方式,需要定义count(记录当前节点出现的次数)和maxCount(出现次数最多的节点),再定义一个pre作为记录节点方便比较.

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
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//定义需要的参数
List<Integer> res = new ArrayList<>();;
int count = 0;
int maxCount = 0;
TreeNode pre = null;
public int[] findMode(TreeNode root) {
//初始化
findMode1(root);
int[] result = new int[res.size()];
for(int i = 0; i < res.size();i++) {
result[i] = res.get(i);
}
return result;
}
void findMode1(TreeNode root) {
if(root == null){
return;
}
findMode1(root.left);
if(pre == null || pre.val != root.val) {
count = 1;
}else {
count++;
}
if(count > maxCount) {
//清除后更新
res.clear();
res.add(root.val);
maxCount = count;
}else if(count == maxCount) {
res.add(root.val);
}
pre = root;
findMode1(root.right);
}
}

二叉搜索树的最近公共祖先

link:236. 二叉树的最近公共祖先 - 力扣(LeetCode)

思路分析

可以使用两个栈来存储从根节点到 pq 的路径,然后通过比较这两个路径来找到它们的最低公共祖先

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
private boolean getPath(TreeNode root, TreeNode node, Stack<TreeNode> stack) {
if (root == null || node == null) {
return false;
}
stack.push(root);
if (root == node) {
return true;
}
boolean flg = getPath(root.left, node, stack);
if (flg) {
return true;
}
boolean flg2 = getPath(root.right, node, stack);
if (flg2) {
return true;
}
stack.pop();
return false;
}

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
Stack<TreeNode> stackP = new Stack<>();
Stack<TreeNode> stackQ = new Stack<>();

getPath(root, p, stackP);
getPath(root, q, stackQ);

int sizeP = stackP.size();
int sizeQ = stackQ.size();

if (sizeP > sizeQ) {
int size = sizeP - sizeQ;
while (size != 0) {
stackP.pop();
size--;
}
} else {
int size = sizeQ - sizeP;
while (size != 0) {
stackQ.pop();
size--;
}
}
while (!stackP.isEmpty() && !stackQ.isEmpty()) {
if (stackP.peek().equals(stackQ.peek())) {
return stackP.peek();
}
stackP.pop();
stackQ.pop();
}
return null;
}

DFS(后序遍历)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) { // 递归结束条件
return root;
}

// 后序遍历
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

if (left == null && right == null) { // 若未找到节点 p 或 q
return null;
} else if (left == null && right != null) { // 若找到一个节点
return right;
} else if (left != null && right == null) { // 若找到一个节点
return left;
} else { // 若找到两个节点
return root;
}
}