代码随想录第二十一天
- Leetcode 530. 二叉搜索树的最小绝对差
- Leetcode 501. 二叉搜索树中的众数
- Leetcode 236. 二叉树的最近公共祖先
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,如果其中一个不为空,另一个为空,说明不为空的那个为最近公共祖先,如果两个都不为空,则当前节点为最近公共祖先!!!
代码:
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);//如果左右两边都没有,直接返回nullif (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)