东哥带你刷二叉树(后序篇) :: labuladong的算法小抄 #991
Replies: 29 comments 4 replies
-
/**
* @param {TreeNode} root
* @return {TreeNode[]}
*/
let memo = new Map()
let res = []
function findDuplicateSubtrees(root) {
traverse(root)
return res
}
function traverse(root) {
if(root == null) {
return '#'
}
let leftValue = traverse(root.left)
let rightValue = traverse(root.right)
let subTree = leftValue + ',' + rightValue + ',' + root.val
let freq = memo.get(subTree) || 0
if(freq == 1) {
res.push(root)
}
memo.set(subTree, freq + 1)
return subTree
} 这个好奇怪,同东东的java代码逻辑一模一样, leetcode测试没通过, 并且力扣里面执行代码和提交代码对测试用例的结果不同?执行代码是对的,提交时,同一用例说我输出错误 |
Beta Was this translation helpful? Give feedback.
-
@lovelyJason |
Beta Was this translation helpful? Give feedback.
-
python 版 # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
self.res=[]
self.hashmap={}
def traverse(self,root):
if root==None:
return '#'
left=self.traverse(root.left)
right=self.traverse(root.right)
subtree=left+","+right+","+str(root.val)
fre=self.hashmap.get(subtree,0)
if fre==1:
self.res.append(root)
self.hashmap[subtree]=fre+1
return subtree
def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
self.traverse(root)
return self.res |
Beta Was this translation helpful? Give feedback.
-
嗯是这个问题 |
Beta Was this translation helpful? Give feedback.
-
可恶的合作方(bushi) |
Beta Was this translation helpful? Give feedback.
-
为什么left + "," + root.val + "," + right ; 有一个用例会错误。。感觉思路是一样的啊 |
Beta Was this translation helpful? Give feedback.
-
@ayccwhd 因为中序遍历的话, 左节点为None, 和右节点为None, 序列化出来是同一个string
你可以试试这两个 |
Beta Was this translation helpful? Give feedback.
-
@KevinZhou92 感谢,这里困惑了好久 |
Beta Was this translation helpful? Give feedback.
-
javascript version var findDuplicateSubtrees = function(root) {
// 记录所有子树以及出现的次数
let mapSet = new Map();
// 记录重复的子树根节点
let res = [];
function traverse(node) {
// base case 空节点使用特殊的字符表示
if (!node) {
return "#";
}
let leftNode = traverse(node.left);
let rightNode = traverse(node.right);
/****** 后序位置 ******/
// 将左右子树和node节点序列化成字符串
let nodeString = leftNode + "," + rightNode + "," + node.val;
// 让每个节点把自己的序列化结果存进去 查询得到有没有其他节点的子树与自己重复
let freq = mapSet.get(nodeString) || 0;
// 多次重复也只会被加入结果集一次
if (freq == 1){
res.push(node);
}
// 给子树对应的出现次数加一
mapSet.set(nodeString, freq + 1);
/*********************/
return nodeString;
}
traverse(root);
return res;
}; |
Beta Was this translation helpful? Give feedback.
-
有意思,这题又正好能用上前文序列化篇的内容,没去公众号看解法,但是感觉使用序列化一下子树,然后放到map里面存一下貌似就行了 |
Beta Was this translation helpful? Give feedback.
-
python代码: # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
import collections
NULL = "201"
class Solution:
def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
subtree_dict = collections.defaultdict(int)
self.ans = []
def traverse(root):
if not root:
return NULL
left_preorder = traverse(root.left)
right_preorder = traverse(root.right)
preorder = str(root.val) + " " +left_preorder + " " + right_preorder
subtree_dict[preorder] += 1
if subtree_dict[preorder] == 2:
self.ans.append(root)
return preorder
traverse(root)
return self.ans |
Beta Was this translation helpful? Give feedback.
-
@KevinZhou92 这两个中序遍历一个是:0,0,null,一个是null,0,0,不一样啊 |
Beta Was this translation helpful? Give feedback.
-
@fly-adser 不是, 两个都是 #,0,#,0,# |
Beta Was this translation helpful? Give feedback.
-
东哥,这题能不能把每个节点的序列化结果都人丢进hashset里头,最后都拿出来存到list中进行返回? |
Beta Was this translation helpful? Give feedback.
-
from collections import defaultdict
class Solution:
def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]:
if not root:
return root
hashmap = defaultdict(lambda: 0)
res = []
def traverse(root):
if not root:
return "#"
left_nodes = traverse(root.left)
right_nodes = traverse(root.right)
res_str = left_nodes + ',' + right_nodes + ',' + str(root.val)
if res_str in hashmap and hashmap[res_str] == 1:
res.append(root)
hashmap[res_str] += 1
return res_str
traverse(root)
return res |
Beta Was this translation helpful? Give feedback.
-
在美国不能够用微信付款。有没有其它付款办法? |
Beta Was this translation helpful? Give feedback.
-
请问有朋友遇到这个test case怕不过的吗,我这显示175/176 |
Beta Was this translation helpful? Give feedback.
-
打卡 然后“子树”用序列化的字符结果表示。key不能是树,也不能是list,但可以是字符串。 |
Beta Was this translation helpful? Give feedback.
-
这个case过不去 |
Beta Was this translation helpful? Give feedback.
-
java版 class Solution {
HashMap<String, Integer> map = new HashMap<>();
List<TreeNode> res = new ArrayList<>();
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
dfs(root);
return res;
}
public String dfs(TreeNode root) {
StringBuilder sb = new StringBuilder();
if (root == null) return "#";
String key = sb.append(root.val).append("-").append(dfs(root.left)).append(dfs(root.right)).toString();
map.put(key, map.getOrDefault(key, 0) + 1);
if(map.get(key) == 2) {
res.add(root);
}
return key;
}
} |
Beta Was this translation helpful? Give feedback.
-
go version: /**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
// postorder is commonly used for resolve kinds of subtree problem
func findDuplicateSubtrees(root *TreeNode) []*TreeNode {
res, set := []*TreeNode{}, map[string]int{}
dfs(root, set, &res)
return res
}
func dfs(root *TreeNode, set map[string]int, res *[]*TreeNode) string {
if root == nil {return "#"}
l := dfs(root.Left, set, res)
r := dfs(root.Right, set, res)
subTreeStr := l + "," + r + "," + strconv.Itoa(root.Val)
set[subTreeStr]++
// add to result when we only found the subTreeString appeared at the second time
if count, _ := set[subTreeStr]; count == 2{
*res = append(*res, root)
}
return subTreeStr
}``` |
Beta Was this translation helpful? Give feedback.
-
c++ version class Solution {
public:
unordered_map<string,int> hashmap;
vector<TreeNode*>res;
string traverse(TreeNode* root)
{
if(root==NULL)
return "#";
string left=traverse(root->left);
string right=traverse(root->right);
string subtree=left+","+right+","+to_string(root->val);
if(hashmap[subtree]==1)
res.push_back(root);
hashmap[subtree]++;
return subtree;
}
vector<TreeNode*> findDuplicateSubtrees(TreeNode* root)
{
traverse(root);
return res;
}
}; |
Beta Was this translation helpful? Give feedback.
-
还有一个三元组方法,希望东哥可以更新进来~ |
Beta Was this translation helpful? Give feedback.
-
序列化没加逗号,map中会检测到重复的key,很奇怪。 |
Beta Was this translation helpful? Give feedback.
-
Go version /**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
import "strconv"
func findDuplicateSubtrees(root *TreeNode) []*TreeNode {
res := make([]*TreeNode, 0)
nodeSeqMap := make(map[string]int)
var serialize func(*TreeNode) string
serialize = func(node *TreeNode) string {
if node == nil {
return "#"
}
seq := serialize(node.Left) + "," + serialize(node.Right) + "," + strconv.Itoa(node.Val)
if nodeSeqMap[seq] == 1 {
res = append(res, node)
}
nodeSeqMap[seq] += 1
return seq
}
serialize(root)
return res
} |
Beta Was this translation helpful? Give feedback.
-
文章链接点这里:东哥带你刷二叉树(后序篇)
评论礼仪 见这里,违者直接拉黑。
Beta Was this translation helpful? Give feedback.
All reactions