算法从0到1 Day 17 二叉树part 06
Day 17 二叉树part 06
530. 二叉搜索树的最小绝对差
看到public int getMinimumDifference(TreeNode root)题目的返回值是int类型,当时我尝试写了一下,root==null的时候我不知道返回什么,0?-1?似乎都是不行的,所以我就定义了traversal,如何把返回的minValue放到全居遍历中,主函数调用traversal之后,return全局变量就可以了
if (root == null) return 0;
注意主函数的判断返回。
private TreeNode pre = null;private int minValue = Integer.MAX_VALUE;public int getMinimumDifference(TreeNode root) {if (root == null) return 0;traversal(root);return minValue;}private void traversal(TreeNode root) {if (root == null) return;traversal(root.left);if (pre != null) {int value = root.val - pre.val;minValue = Math.min(minValue, value);}pre = root;traversal(root.right);}
501. 二叉搜索树中的众数
这个众数可以是很多个
只有二叉搜索树的中序遍历才是有序的
可以先遍历一遍二叉树,查询最高出现频率是多少,然后再遍历当前节点和前一节点相等就++,之后等于最高频率的数就收集
很多递归逻辑,要求我们定义的是全局遍历,因为我们一次递归的变量我们是存留不住的,等递归结束了,我们就跳出了。
我们一般树全部遍历一遍,我们就会用到void,如果从树中求单条路径,我们就需要用返回值。
问题:是用集合接收吗?不知道怎么去将集合转化为数组。 直接用集合遍历,然后用数组收集(数组的长度继承list的长度)
private TreeNode pre = null;private int count = 0;private int maxCount = 0;private List<Integer> list = new ArrayList<>();public int[] findMode(TreeNode root) {traversal(root);int[] result = new int[list.size()];for (int i = 0; i < list.size(); i++) {result[i] = list.get(i);}return result;}public void traversal(TreeNode cur) {if (cur == null) return;traversal(cur.left);//计数和更新分开if (pre == null || pre.val != cur.val) {count = 1; //一开始pre==null初始值为1,发现当前节点值与前一个节点值不相等也是为1} else {count++; //当前节点值与前一个节点值相等就+1}if (maxCount < count) {//当前频率最大的历史的最大频率,就说明之前的是不符合频率最高这一特性,所以我们就替换,重置最大频率,清空list存放最大频率的集合maxCount = count;list.clear();list.add(cur.val);} else if (maxCount == count) {//当前最大频率等于历史最大频率的就收集,说明众数是多个list.add(cur.val);}pre = cur;traversal(cur.right);}
236. 二叉树的最近公共祖先
一定要后序遍历,因为我们需要根据左右返回的结果。
不符合就返回null,符合就把节点返回上去,上面会接收
情况1:p、q互不为最近公共祖先
情况2:p或q为另外一个的最近公共祖先(被包含在一个树中)
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root == null) return root;//root为null,返回的root也就是nullif (root == q || root == p) return root;//因为root为q、或者q,返回root就是返回q、p本身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;//在p、q都出现在树中时,左不为空,右为空,说明其中一个被包含在p的子节点当中。if (left == null && right != null) return right;//同理,也是如此return null; //left与right都为0的情况}
开头的判断其实可以合并
if (root == q || root == p || root == null) return root;