题目大意:
在受污染的二叉树中查找元素
给出一个满足下述规则的二叉树:
- root.val == 0
- 如果 treeNode.val == x 且 treeNode.left != null,那么 treeNode.left.val == 2 * x + 1
- 如果 treeNode.val == x 且 treeNode.right != null,那么 treeNode.right.val == 2 * x + 2
现在这个二叉树受到「污染」,所有的 treeNode.val
都变成了 -1
。
请你先还原二叉树,然后实现 FindElements
类:
- FindElements(TreeNode* root) 用受污染的二叉树初始化对象,你需要先把它还原。
- bool find(int target) 判断目标值 target 是否存在于还原后的二叉树中并返回结果。
示例 1:
输入: ["FindElements","find","find"] [[[-1,null,-1]],[1],[2]] 输出: [null,false,true] 解释: FindElements findElements = new FindElements([-1,null,-1]); findElements.find(1); // return False findElements.find(2); // return True
示例 2:
输入: ["FindElements","find","find","find"] [[[-1,-1,-1,-1,-1]],[1],[3],[5]] 输出: [null,true,true,false] 解释: FindElements findElements = new FindElements([-1,-1,-1,-1,-1]); findElements.find(1); // return True findElements.find(3); // return True findElements.find(5); // return False
示例 3:
输入: ["FindElements","find","find","find","find"] [[[-1,null,-1,-1,null,-1]],[2],[3],[4],[5]] 输出: [null,true,false,false,true] 解释: FindElements findElements = new FindElements([-1,null,-1,-1,null,-1]); findElements.find(2); // return True findElements.find(3); // return False findElements.find(4); // return False findElements.find(5); // return True
提示:
- TreeNode.val == -1
- 二叉树的高度不超过 20
- 节点的总数在 [1, 10^4] 之间
- 调用 find() 的总次数在 [1, 10^4] 之间
- 0 <= target <= 10^6
如果想查看本题目是哪家公司的面试题,请参考以下免费链接: https://leetcode.jp/problemdetail.php?id=1261
解题思路分析:
题目表述的十分清楚,并且难度也不大,先递归一遍二叉树,将每个节点按照要求附上值。查找时,可以使用与赋值时相同的递归思路,找到节点中是否含有target的数字即可。不做优化的情况下本题也可以通过所有测试用例,但执行时间相对较长,大概600多毫秒。做优化时,我们可以考虑给搜索剪枝,因为随着节点的向下延伸,节点的值是在不断变大,因此当节点大于target时可以直接返回false。优化后,执行时间骤减到100多毫秒,不过这个结果还是难以满意。其实最简单粗暴的方式是,在第一步给每个节点赋值时,我们可以使用一个集合记录下所有出现过的节点值,查找时,我们直接看集合中是否存在该值即可。
实现代码:
TreeNode mRoot; // 根节点 // 保存所有节点值的集合 Set<Integer> set = new HashSet<>(); public FindElements(TreeNode root) { root.val=0; // 根节点初始化为0 mRoot=root; // 将root保存到全局变量 helper(root); // 递归给每一个节点赋值 } void helper(TreeNode root){ set.add(root.val); // 将当前节点值加入集合 if(root.left!=null){ // 如果左子节点不为空 // 左子节点赋值位当前值乘以2加1 root.left.val=root.val*2+1; // 递归左子节点 helper(root.left); } if(root.right!=null){ // 如果右子节点不为空 // 右子节点赋值位当前值乘以2加2 root.right.val=root.val*2+2; // 递归右子节点 helper(root.right); } } public boolean find(int target) { // 查看集合中是否存在target return set.contains(target); }
本题解法执行时间为20ms。
Runtime: 20 ms, faster than 99.14% of Java online submissions for Find Elements in a Contaminated Binary Tree.
Memory Usage: 48.9 MB, less than 100.00% of Java online submissions for Find Elements in a Contaminated Binary Tree.
本网站文章均为原创内容,并可随意转载,但请标明本文链接如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: http://leetcode.jp/leetcode-1261-find-elements-in-a-contaminated-binary-tree-解题思路分析/