Leetcode 530. 二叉搜索树的最小绝对差
题目链接: 二叉搜索树的最小绝对差
自己的思路:和验证二叉搜索树一样的思路!可以求每个相邻节点的差值的绝对值,然后和之前的差值的绝对值进行比较,取最小的为新的res;递归三部曲:1、传入参数:当前节点;2、终止条件:如果当前节点为空,直接返回;3、单层递归逻辑:中序遍历!!因为中序遍历可以保证是递增的,这样就不会跳着比较,所以先递归左子树,然后中节点和前一个节点求差值的绝对值和res比较,取最小值为res,然后再定义新的pre,再进行右子树的遍历即可!!!
正确思路:
代码:
class Solution {
int res = Integer.MAX_VALUE;
TreeNode pre;
public int getMinimumDifference(TreeNode root) {
if (root==null) return 0;
getmin(root);
return res;
}
public void getmin(TreeNode root){
if (root==null) return;
//左递归
getmin(root.left);
//求上一个节点和此节点的最小值和之前的差进行比较
if (pre!=null){
res = Math.min(res,Math.abs(pre.val-root.val));
}
//重新表示上一个节点
pre = root;
//右递归
getmin(root.right);
}
}
复杂度分析:
时间复杂度:
O
(
n
)
\mathcal{O}(n)
O(n)
空间复杂度:
O
(
1
)
\mathcal{O}(1)
O(1)
Leetcode 501. 二叉搜索树中的众数
题目链接: 二叉搜索树中的众数
自己的思路:没想到!!!!
正确思路:比较笨的方法是遍历两次二叉树,然后找其中最大的值就可以;但是这里是使用了一点代码技巧来处理这个问题,所以使用一次遍历就可以;具体的思路为:二叉搜索树一定是中序遍历!!!!这样可以保证有序,主要是处理中的逻辑,我们可以定义三个变量,count用于存储当前结点的值出现的次数,maxcount用于存储出现的最多的结点出现的次数,pre存储上一个节点;首先是计数阶段:当pre是空的时候,那也就是说node现在是出于叶子节点,记录它的count值为1,当pre的结点值等于node的结点值的时候,说明出现了相同的节点值,则count++,当pre的结点值不等于node的结点值时,说明出现了不同的节点值,重置count为1;然后是加入结果阶段:当count==maxcount的时候,说明当前的次数和最大的次数相同,当前结点值加入到结果集中,如果count>maxcount的时候,说明之前的maxcount并不是全局的最大,所以把之前的res中的所有元素清空,然后再加入新的结果,并且把maxcount赋值为count;递归三部曲:1、传入参数:当前节点;2、终止条件:当当前节点为空的时候,返回;3、单层逻辑:先左递归,然后处理中间节点,然后右递归!!!
代码:
class Solution {
List<Integer> res = new ArrayList<>();
int count = 0;
int maxcount = 0;
TreeNode pre;
public int[] findMode(TreeNode root) {
addMode(root);
int [] re = new int[res.size()];
for (int i =0;i<re.length;i++){
re[i] = res.get(i);
}
return re;
}
public void addMode(TreeNode node){
if (node==null) return;
addMode(node.left);
//计数阶段
if (pre==null) count=1;
else if (pre.val==node.val){
count++;
}
else count=1;
//加结果阶段
if (count>maxcount){
maxcount = count;
res.clear();
res.add(node.val);
}else if (count==maxcount){
res.add(node.val);
}
pre = node;
addMode(node.right);
}
}
复杂度分析:
时间复杂度:
O
(
n
)
\mathcal{O}(n)
O(n)
空间复杂度:
O
(
1
)
\mathcal{O}(1)
O(1)
Leetcode 236. 二叉树的最近公共祖先
题目链接: 二叉树的最近公共祖先
自己的思路:没想到!!!
正确思路:主要是遍历顺序,使用后序遍历出来,自底向上地返回;递归三部曲:1、传入参数:当前结点、结点p、结点q;2、终止条件:当当前结点是空或者p和q时,直接返回当前结点即可,因为没有比这个更深的结点了;3、单层递归逻辑:先左右递归左右子树查找左右子树分别对p和q的最近公共祖先,得到left和right,如果两个都为空,说明没找到,直接返回null,如果其中一个不为空,另一个为空,说明不为空的那个为最近公共祖先,如果两个都不为空,则当前节点为最近公共祖先!!!
代码:文章来源:https://www.toymoban.com/news/detail-597592.html
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
//如果当前结点就是空或者p和q的话,直接返回当前结点
if (root==null||root==p||root==q){
return root;
}
//递归左右子树
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
//如果左右两边都没有,直接返回null
if (left==null&&right==null) return null;
//左边有返回左边,右边有返回右边
if (left==null||right==null){
return left==null?right:left;
}
//左右两边都有返回当前结点
return root;
}
}
复杂度分析:
时间复杂度:
O
(
n
)
\mathcal{O}(n)
O(n)
空间复杂度:
O
(
1
)
\mathcal{O}(1)
O(1)文章来源地址https://www.toymoban.com/news/detail-597592.html
到了这里,关于代码随想录第二十一天的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!