通常使用多行的节点、父节点表示一棵树,比如
西安 陕西 陕西 中国 江西 中国 中国 亚洲 泰国 亚洲
输入一个节点之后,请打印出来树中他的所有下层节点
第一行输入行数
接着是多行数据,每行以空格区分节点和父节点
最后是查询节点
树中的节点是唯一的,不会出现两个节点,是同一个名字
输出查询节点的所有下层节点。以字典序排序
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
。
# 题目: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)
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);
}
}
}
#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;
}
# 题目: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)
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);
}
}
}
}
#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算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
绿色聊天软件戳 od1336
了解更多