652. Find Duplicate Subtrees

LeetCode medium оригинал: C# #csharp #hash-table #leetcode #medium #search #string #tree #two-pointers

Если задан корень бинарного дерева, верните все дублирующие поддеревья. Для каждого вида дублирующих поддеревьев достаточно вернуть корневой узел любого из них. Два дерева являются дублирующими, если они имеют одинаковую структуру с одинаковыми значениями узлов.

Пример:

Input: root = [1,2,3,4,null,2,4,null,null,4]

Output: [[2,4],[4]]

C# решение

сопоставлено/оригинал
public class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int val = 0, TreeNode left = null, TreeNode right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
public class Solution {
    public IList<TreeNode> FindDuplicateSubtrees(TreeNode root) {
        Dictionary<string, int> count = new Dictionary<string, int>();
        List<TreeNode> result = new List<TreeNode>();
        Serialize(root, count, result);
        return result;
    }
    private string Serialize(TreeNode node, Dictionary<string, int> count, List<TreeNode> result) {
        if (node == null) return "#";
        string serial = node.val + "," + Serialize(node.left, count, result) + "," + Serialize(node.right, count, result);
        if (count.ContainsKey(serial)) {
            count[serial]++;
        } else {
            count[serial] = 1;
        }
        if (count[serial] == 2) {
            result.Add(node);
        }
        return serial;
    }
}

C++ решение

auto-draft, проверить перед отправкой
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
public class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int val = 0, TreeNode left = null, TreeNode right = null) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
class Solution {
public:
    public IList<TreeNode> FindDuplicateSubtrees(TreeNode root) {
        unordered_map<string, int> count = new unordered_map<string, int>();
        List<TreeNode> result = new List<TreeNode>();
        Serialize(root, count, result);
        return result;
    }
    private string Serialize(TreeNode node, unordered_map<string, int> count, List<TreeNode> result) {
        if (node == null) return "#";
        string serial = node.val + "," + Serialize(node.left, count, result) + "," + Serialize(node.right, count, result);
        if (count.count(serial)) {
            count[serial]++;
        } else {
            count[serial] = 1;
        }
        if (count[serial] == 2) {
            result.push_back(node);
        }
        return serial;
    }
}

Java решение

сопоставлено/оригинал
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val) { this.val = val; }
}

public class Solution {
    public List<TreeNode> findDuplicateSubtrees(TreeNode root) {
        Map<String, Integer> count = new HashMap<>();
        List<TreeNode> result = new ArrayList<>();
        serialize(root, count, result);
        return result;
    }

    private String serialize(TreeNode node, Map<String, Integer> count, List<TreeNode> result) {
        if (node == null) return "#";
        String serial = node.val + "," + serialize(node.left, count, result) + "," + serialize(node.right, count, result);
        count.put(serial, count.getOrDefault(serial, 0) + 1);
        if (count.get(serial) == 2) {
            result.add(node);
        }
        return serial;
    }
}

JavaScript решение

сопоставлено/оригинал
function TreeNode(val, left, right) {
    this.val = (val===undefined ? 0 : val)
    this.left = (left===undefined ? null : left)
    this.right = (right===undefined ? null : right)
}

var findDuplicateSubtrees = function(root) {
    const count = new Map();
    const result = [];
    
    const serialize = (node) => {
        if (!node) return "#";
        const serial = `${node.val},${serialize(node.left)},${serialize(node.right)}`;
        count.set(serial, (count.get(serial) || 0) + 1);
        if (count.get(serial) === 2) {
            result.push(node);
        }
        return serial;
    };
    
    serialize(root);
    return result;
};

Python решение

сопоставлено/оригинал
from collections import defaultdict

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def findDuplicateSubtrees(root):
    def serialize(node):
        if not node:
            return "#"
        serial = f"{node.val},{serialize(node.left)},{serialize(node.right)}"
        count[serial] += 1
        if count[serial] == 2:
            result.append(node)
        return serial
    
    count = defaultdict(int)
    result = []
    serialize(root)
    return result

Go решение

сопоставлено/оригинал
package main

import (
    "fmt"
    "strconv"
    "strings"
)

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

func findDuplicateSubtrees(root *TreeNode) []*TreeNode {
    count := make(map[string]int)
    result := []*TreeNode{}
    serialize(root, count, &result)
    return result
}

func serialize(node *TreeNode, count map[string]int, result *[]*TreeNode) string {
    if node == nil {
        return "#"
    }
    serial := strconv.Itoa(node.Val) + "," + serialize(node.Left, count, result) + "," + serialize(node.Right, count, result)
    count[serial]++
    if count[serial] == 2 {
        *result = append(*result, node)
    }
    return serial
}

func main() {
    root := &TreeNode{Val: 1, Left: &TreeNode{Val: 2, Left: &TreeNode{Val: 4}}, Right: &TreeNode{Val: 3, Left: &TreeNode{Val: 2, Left: &TreeNode{Val: 4}}, Right: &TreeNode{Val: 4}}}
    result := findDuplicateSubtrees(root)
    for _, node := range result {
        fmt.Println(node.Val)
    }
}

Algorithm

Выполните обход дерева и используйте сериализацию для представления каждого поддерева.

Храните все сериализованные представления поддеревьев в хэш-таблице и отслеживайте частоту их появления.

Найдите поддеревья, которые появляются более одного раза, и верните корневые узлы этих поддеревьев.

😎

Вакансии для этой задачи

Показаны активные вакансии с пересечением по тегам задачи.

Все вакансии
Активных вакансий пока нет.