530:二叉搜索树的最小绝对值差
记住两点:1)二叉搜索树是有序的,其中序遍历是一个递增序列
递归法:利用中序遍历先得到一个递增列表,再对列表中的元素遍历求出最小绝对值差
class Solution {
public int getMinimumDifference(TreeNode root) {
List<Integer> list = new LinkedList<>();
search(root, list);
int min = Integer.MAX_VALUE;
for (int i = 1; i < list.size(); i++) {
if ((list.get(i)-list.get(i-1))<min) {
min = list.get(i)-list.get(i-1);
}
}
return min;
}
public void search(TreeNode root, List<Integer> list) {
if (root==null) {
return;
}
if (root.left!=null) {
search(root.left, list);
}
list.add(root.val);
if (root.right!=null) {
search(root.right, list);
}
}
}
递归法:直接在中序遍历中找到最小绝对值差
class Solution {
int min = Integer.MAX_VALUE;
TreeNode pre = null;
public int getMinimumDifference(TreeNode root) {
search(root);
return min;
}
public void search(TreeNode root) {
if (root == null) {
return;
}
if (root.left != null) {
search(root.left);
}
if (pre!=null && (root.val-pre.val)<min) {
min = root.val - pre.val;
}
pre = root;
if (root.right != null) {
search(root.right);
}
}
}
迭代法:
class Solution {
public int getMinimumDifference(TreeNode root) {
int min = Integer.MAX_VALUE;
TreeNode pre = null;
Stack<TreeNode> stack = new Stack<>();
while (root!=null || !stack.isEmpty()) {
if (root!=null) {
stack.push(root);
root = root.left;
}else {
root = stack.pop();
if (pre!=null && (root.val - pre.val) < min) {
min = root.val - pre.val;
}
pre = root;
root = root.right;
}
}
return min;
}
}
501:二叉搜索树中的众数
递归法:利用中序遍历求解
class Solution {
TreeNode pre = null;
int max = 1;
int count = 1;
HashSet<Integer> set = new HashSet<>();
public int[] findMode(TreeNode root) {
if (root==null) {
return null;
}
find(root);
return set.stream().mapToInt(x->x).toArray();
}
public void find(TreeNode root) {
if (root == null) {
return;
}
// 左
if (root.left != null) {
find(root.left);
}
// 处理中间节点
if (pre!=null) {
// 如果遍历的节点值等于pre节点的值,count+1
if (root.val == pre.val) {
count++;
}else if (root.val > pre.val) {
// 当遍历节点值大于pre节点的时候,说明开始找新一轮众数了
pre = root;
count = 1;
}
// 当众数值大于最大值的时候,更新最大值,并且把set清空,说明之前的不是众数
// 并把现在找到的值添加到set
if (count > max) {
max = count;
set.clear();
set.add(pre.val);
} else if (count == max) {// 当众数和max一样的时候,说明找到多个众数
set.add(pre.val);
}
}else {// 一开始pre为空结点,所以需要令其等于root
pre = root;
set.add(pre.val);
}
// 右
if (root.right != null) {
find(root.right);
}
}
}
迭代法:在中序遍历的基础上
class Solution {
TreeNode pre = null;
int max = 1;
int count = 1;
HashSet<Integer> set = new HashSet<>();
public int[] findMode(TreeNode root) {
if (root == null) {
return null;
}
Stack<TreeNode> stack = new Stack<>();
while (root!=null || !stack.isEmpty()) {
if (root!=null) {
stack.push(root);
root = root.left;
}else {
root = stack.pop();
if (pre==null) {
pre = root;
set.add(pre.val);
}else{
// 如果遍历的节点值等于pre节点的值,count+1
if (root.val == pre.val) {
count++;
}else if (root.val > pre.val) {
// 当遍历节点值大于pre节点的时候,说明开始找新一轮众数了
pre = root;
count = 1;
}
// 当众数值大于最大值的时候,更新最大值,并且把set清空,说明之前的不是众数
// 并把现在找到的值添加到set
if (count > max) {
max = count;
set.clear();
set.add(pre.val);
} else if (count == max) {// 当众数和max一样的时候,说明找到多个众数
set.add(pre.val);
}
}
root = root.right;
}
}
return set.stream().mapToInt(x -> x).toArray();
}
}
236:二叉树的最近公共祖先
递归:用后序遍历方法,从根部逐渐向上遍历。
递归出口:遍历到空结点、p节点或者q节点后返回该节点
单层递归逻辑:当前遍历节点的左右节点都不为空时,返回该节点,其中一个节点不为空时,返回相应节点。
class Solution {
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) {
return root;
}
if (left!=null && right==null) {
return left;
}else if (left==null && right!=null) {
return right;
}
return null;
}
}