【限时免费】20天拿下华为OD笔试之【DFS/BFS】2023B-树状结构查询【欧弟算法】全网注释最详细分类最全的华为OD真题题解

文章目录

  • 题目描述与示例
    • 题目描述
    • 输入描述
    • 输出描述
    • 示例
      • 输入
      • 输出
  • 解题思路
  • 代码
    • 解法一:DFS
      • python
      • java
      • cpp
    • 解法二:BFS
      • python
      • java
      • cpp
    • 时空复杂度
  • 华为OD算法/大厂面试高频题算法练习冲刺训练

题目描述与示例

题目描述

通常使用多行的节点、父节点表示一棵树,比如

西安 陕西 陕西 中国 江西 中国 中国 亚洲 泰国 亚洲

输入一个节点之后,请打印出来树中他的所有下层节点

输入描述

第一行输入行数

接着是多行数据,每行以空格区分节点和父节点

最后是查询节点

树中的节点是唯一的,不会出现两个节点,是同一个名字

输出描述

输出查询节点的所有下层节点。以字典序排序

示例

输入

5
b a
c a
d c
e c
f d
c

输出

d
e
f

解题思路

本题属于非常常规的搜索题目,用DFS或BFS都可以完成。

首先使用哈希表构建邻接表children_dict,对输入进行建树处理,即

n = int(input())
children_dict = defaultdict(list)

for _ in range(n):
    child, parent = input().split()
    children_dict[parent].append(child)

如果使用DFS,则递归函数如下

def dfs(node, ans, children_dic):
    ans.append(node)
    for child in children_dic[node]:
        dfs(child, ans, children_dic)

如果使用BFS,则函数如下

def bfs(target, ans, children_dic):
    q = deque()
    q.append(target)
    while q:
        node = q.popleft()
        for child in children_dic[node]:
            q.append(child)
            ans.append(child)

在输出结果的时候,需要注意不能输出target

代码

解法一:DFS

python

# 题目:2023B-树状结构查询
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:DFS
# 代码看不懂的地方,请直接在群上提问


from collections import defaultdict


# dfs函数
def dfs(node, ans, children_dic):
    # 将node加入ans中
    ans.append(node)
    # 遍历node的所有子节点,递归调用子节点
    for child in children_dic[node]:
        dfs(child, ans, children_dic)

# 输入行数
n = int(input())
# 使用哈希表,储存某一个节点所有子节点构成的列表
# k为某个父节点,v为其所有子节点构成的列表
children_dict = defaultdict(list)

# 遍历N行,输入所有的父子节点连接情况
for _ in range(n):
    # 获得子节点和父节点,注意父节点在后
    child, parent = input().split()
    children_dict[parent].append(child)

# 输入查询节点
target = input()

# 初始化答案列表
ans = list()
# dfs入口,传入的节点为查询节点target
dfs(target, ans, children_dict)

# 根据字典序进行排序
ans.sort()
# 逐行输出ans中的所有值,要注意ans中包含了查询target
# 根据题意target是不应该输出的,需要多做一步判断
for node in ans:
    if node != target:
        print(node)

java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        scanner.nextLine(); // Consume the newline

        Map<String, List<String>> childrenMap = new HashMap<>();

        for (int i = 0; i < n; i++) {
            String[] input = scanner.nextLine().split(" ");
            String child = input[0];
            String parent = input[1];
            childrenMap.computeIfAbsent(parent, k -> new ArrayList<>()).add(child);
        }

        String target = scanner.nextLine();
        List<String> ans = new ArrayList<>();

        dfs(target, ans, childrenMap);

        Collections.sort(ans);
        for (String node : ans) {
            if (!node.equals(target)) {
                System.out.println(node);
            }
        }
    }

    private static void dfs(String node, List<String> ans, Map<String, List<String>> childrenMap) {
        ans.add(node);
        List<String> children = childrenMap.getOrDefault(node, new ArrayList<>());
        for (String child : children) {
            dfs(child, ans, childrenMap);
        }
    }
}

cpp

#include 
#include 
#include 
#include 

using namespace std;

void dfs(string node, vector<string>& ans, map<string, vector<string>>& childrenMap) {
    ans.push_back(node);
    vector<string>& children = childrenMap[node];
    for (const string& child : children) {
        dfs(child, ans, childrenMap);
    }
}

int main() {
    int n;
    cin >> n;
    cin.ignore(); // Consume the newline

    map<string, vector<string>> childrenMap;

    for (int i = 0; i < n; i++) {
        string child, parent;
        cin >> child >> parent;
        childrenMap[parent].push_back(child);
    }

    string target;
    cin >> target;

    vector<string> ans;

    dfs(target, ans, childrenMap);

    sort(ans.begin(), ans.end());

    for (const string& node : ans) {
        if (node != target) {
            cout << node << endl;
        }
    }

    return 0;
}

解法二:BFS

python

# 题目:2023B-树状结构查询
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:BFS
# 代码看不懂的地方,请直接在群上提问


from collections import defaultdict, deque


# bfs函数
def bfs(target, ans, children_dic):
    # 初始化队列,包含节点target
    # 注意target不用加入ans中
    q = deque()
    q.append(target)
    # 进行BFS
    while q:
        # 弹出队头元素node
        node = q.popleft()
        # 考虑node的所有子节点
        for child in children_dic[node]:
            # 将子节点加入q和ans中
            q.append(child)
            ans.append(child)

# 输入行数
n = int(input())
# 使用哈希表,储存某一个节点所有子节点构成的列表
# k为某个父节点,v为其所有子节点构成的列表
children_dict = defaultdict(list)

# 遍历N行,输入所有的父子节点连接情况
for _ in range(n):
    # 获得子节点和父节点,注意父节点在后
    child, parent = input().split()
    children_dict[parent].append(child)

# 输入查询节点
target = input()

# 初始化答案列表
ans = list()
# 进行bfs
bfs(target, ans, children_dict)

# 根据字典序进行排序
ans.sort()
# 逐行输出ans中的所有值
for node in ans:
    print(node)

java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        scanner.nextLine(); // Consume the newline

        Map<String, List<String>> childrenMap = new HashMap<>();

        for (int i = 0; i < n; i++) {
            String[] input = scanner.nextLine().split(" ");
            String child = input[0];
            String parent = input[1];
            childrenMap.computeIfAbsent(parent, k -> new ArrayList<>()).add(child);
        }

        String target = scanner.nextLine();
        List<String> ans = new ArrayList<>();

        bfs(target, ans, childrenMap);

        Collections.sort(ans);
        for (String node : ans) {
            System.out.println(node);
        }
    }

    private static void bfs(String target, List<String> ans, Map<String, List<String>> childrenMap) {
        Queue<String> queue = new LinkedList<>();
        queue.offer(target);

        while (!queue.isEmpty()) {
            String node = queue.poll();
            List<String> children = childrenMap.getOrDefault(node, new ArrayList<>());
            for (String child : children) {
                queue.offer(child);
                ans.add(child);
            }
        }
    }
}

cpp

#include 
#include 
#include 
#include 
#include 

using namespace std;

void bfs(string target, vector<string>& ans, map<string, vector<string>>& childrenMap) {
    queue<string> q;
    q.push(target);

    while (!q.empty()) {
        string node = q.front();
        q.pop();
        vector<string>& children = childrenMap[node];
        for (const string& child : children) {
            q.push(child);
            ans.push_back(child);
        }
    }
}

int main() {
    int n;
    cin >> n;
    cin.ignore(); // Consume the newline

    map<string, vector<string>> childrenMap;

    for (int i = 0; i < n; i++) {
        string child, parent;
        cin >> child >> parent;
        childrenMap[parent].push_back(child);
    }

    string target;
    cin >> target;

    vector<string> ans;

    bfs(target, ans, childrenMap);

    sort(ans.begin(), ans.end());

    for (const string& node : ans) {
        cout << node << endl;
    }

    return 0;
}

时空复杂度

时间复杂度:O(N)。无论是DFS还是BFS,最差的情况都是遍历整棵树。

空间复杂度:O(N)children_dict所占用空间。


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!

  • 课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!

  • 60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接 大厂真题汇总 & OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1336了解更多

你可能感兴趣的:(最新华为OD真题,#,DFS,#,BFS,深度优先,算法,华为od)