📜  门| GATE CS Mock 2018年|问题29(1)

📅  最后修改于: 2023-12-03 15:28:39.880000             🧑  作者: Mango

题目描述

给定一个由n个节点组成的二叉树,每个节点都有一个键和一个值。给定一个整数k和一个字符串S,找到具有键值k和值S的节点的子树中节点的数目。

示例

给定如下的二叉树

        1(/aaa)
       /  \
      2    3(/bbb)
     / \    \
   4    5   6(/ccc)
        \
         7(/ddd)

在此二叉树中,如果k=3,S="bbb",那么返回4。

输入

输入数据的第一行包含一个整数T,表示测试用例的数量。对于每个测试用例,第一行包含一个整数n,表示二叉树中节点的数量。接下来的n行描述每个节点。每行都包含3个整数p,k和s。这些表示每个节点的父节点上的键,该节点的键以及该节点的值。如果一个节点没有父节点,则p将-1。根据键值k的值进行编号,第二行包含一个整数k和一个字符串S。

输出

输出在含有键值k和值S的节点的子树中找到的节点数目。

限制条件

1 ≤ T ≤ 10

1 ≤ n ≤ 10^5

-10^9 ≤ k ≤ 10^9

S仅包含小写字母且长度不超过10

解题思路

这是一道树的DFS题。我们可以先用一个哈希表将节点的键和值关联起来。然后从根节点开始进行DFS,如果遇到了值为S且键为k的节点,那么就返回该节点的子树节点数量即可。

代码如下(Python):

def count_nodes(node, k, s, cnt):
    if not node:
        return 0
    if node['k'] == k and node['s'] == s:
        cnt[0] += 1
    return 1 + count_nodes(node.get('left'), k, s, cnt) + count_nodes(node.get('right'), k, s, cnt)

def solve(tree, k, s):
    nodes = {}
    root = None
    for p, ki, si in tree:
        node = {'k': ki, 's': si}
        nodes[ki] = node
        if p == -1:
            root = node
        else:
            parent = nodes[p]
            if parent.get('left'):
                parent['right'] = node
            else:
                parent['left'] = node
    cnt = [0]
    count_nodes(root, k, s, cnt)
    return cnt[0]

t = int(input())
for _ in range(t):
    n = int(input())
    tree = []
    for _ in range(n):
        tree.append(list(map(int, input().split())))
    k, s = input().split()
    print(solve(tree, int(k), s))

代码解析:

定义一个字典nodes来保存每个节点的信息,包括键和值。再定义一个变量root来保存根节点。接下来,遍历每一个节点,并添加到nodes字典中。如果该节点没有父节点,则该节点为根节点。否则,将该节点添加到父节点的左子树或者右子树中去。最后,从根节点开始进行DFS,如果遇到了值为S且键为k的节点,那么就返回该节点的子树节点数量。

参考资料
  1. Tree Traversals (Inorder, Preorder and Postorder)
  2. Depth-first search