返回
剖析 LeetCode 652 题:寻找重复的子树
后端
2023-12-03 07:34:57
LeetCode 652 题:寻找重复的子树
这道题要求我们找到二叉树中重复的子树。重复的子树是指,在二叉树中存在两个或多个子树,它们的结构和值都完全相同。
对于这道题,我们可以使用深度优先搜索(DFS)算法来解决。深度优先搜索是一种遍历二叉树的算法,它沿着树的深度进行遍历,直到遇到叶子节点,然后回溯到父节点,再继续遍历下一个子树。
在深度优先搜索的过程中,我们可以使用哈希表来存储已经遍历过的子树。当我们遇到一个新的子树时,我们可以将其序列化(将其转换为字符串表示)并将其存储在哈希表中。如果我们发现一个子树已经在哈希表中存在,那么我们就找到了一个重复的子树。
下面是使用 Java、C++ 和 Rust 三种语言编写的解决方案:
Java
import java.util.*;
class Solution {
private Map<String, Integer> map = new HashMap<>();
private List<TreeNode> result = new ArrayList<>();
public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
traverse(root);
return result;
}
private String traverse(TreeNode root) {
if (root == null) {
return "#";
}
String left = traverse(root.left);
String right = traverse(root.right);
String key = left + "," + right + "," + root.val;
int count = map.getOrDefault(key, 0);
if (count == 1) {
result.add(root);
}
map.put(key, count + 1);
return key;
}
}
C++
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
class Solution {
private:
unordered_map<string, int> map;
vector<TreeNode *> result;
public:
vector<TreeNode *> findDuplicateSubtrees(TreeNode *root) {
traverse(root);
return result;
}
private:
string traverse(TreeNode *root) {
if (root == nullptr) {
return "#";
}
string left = traverse(root->left);
string right = traverse(root->right);
string key = left + "," + right + "," + to_string(root->val);
int count = map[key]++;
if (count == 1) {
result.push_back(root);
}
return key;
}
};
Rust
use std::collections::HashMap;
use std::vec::Vec;
#[derive(Debug, PartialEq, Eq)]
struct TreeNode {
val: i32,
left: Option<Box<TreeNode>>,
right: Option<Box<TreeNode>>,
}
impl TreeNode {
#[inline]
fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
}
struct Solution;
impl Solution {
pub fn find_duplicate_subtrees(root: Option<Box<TreeNode>>) -> Vec<Option<Box<TreeNode>>> {
let mut map: HashMap<String, i32> = HashMap::new();
let mut result: Vec<Option<Box<TreeNode>>> = Vec::new();
Self::traverse(&mut map, &mut result, root);
result
}
fn traverse(
map: &mut HashMap<String, i32>,
result: &mut Vec<Option<Box<TreeNode>>>,
root: Option<Box<TreeNode>>,
) -> String {
if root.is_none() {
return "#".to_string();
}
let root = root.unwrap();
let left = Self::traverse(map, result, root.left);
let right = Self::traverse(map, result, root.right);
let key = format!("{},{},{}", left, right, root.val);
let count = map.entry(key.clone()).or_insert(0);
*count += 1;
if *count == 2 {
result.push(Some(Box::new(root)));
}
key
}
}
除了以上三种语言的解决方案,这篇文章还对所使用类和方法进行了学习记录。希望这篇文章能够帮助读者理解 LeetCode 652 题的解法和实现细节。