BAT面试题:请使用递归构建N叉树
题目要求:
现在我们拥有全国的省、市、县、镇的行政信息,比如 浙江省 -> 杭州市 -> 西湖区 --> xx街道,请将这些信息构建成一棵树,根节点为全国,叶子节点为镇。
我的误解:
刚开始我并没有明白题意,走了弯路,只是简单的构建了一个多叉树。代码如下:
import java.util.ArrayList;
import java.util.List;
public class SiteTree {
public final static String COUNTRY = "国";
public final static String PROVINCE = "省";
public final static String CITY = "市";
private static class Node {
private String level; //国》省》市》县》镇
private String name; //例如:山东省、济南市等具体地名
private List<Node> child; //下一级节点列表
private Node(String level, String name) {
this.level = level;
this.name = name;
}
//Getter Setter
}
public static void main(String[] args) {
//声明一个根节点
Node GUO = new Node(SiteTree.COUNTRY, "中国");
//山东省下的市级单位
Node JINAN = new Node(SiteTree.CITY, "济南市");
Node JINING = new Node(SiteTree.CITY, "济宁市");
//将市级节点放入山东省级节点下
Node QLU = new Node(SiteTree.PROVINCE, "山东省");
SiteTree.add(QLU, JINAN, JINING);
//将省级节点放入国级节点下
Node ZJS = new Node(SiteTree.PROVINCE, "浙江省");
SiteTree.add(GUO, QLU, ZJS);
//不再举例...
System.out.println(GUO);
}
public static void add(Node parent, Node... child) {
List<Node> childs = new ArrayList<>();
for (int i = 0; i < child.length; i++) {
childs.add(child[i]);
}
parent.setChild(childs);
}
}
当面试官看到代码后,提示我:你需要实现一个通用的方法。我没太明白,面试官又说:主要考察你对递归的使用。
看到这里,我忽然明白了面试官的意图:使用递归去构建N叉树。
摆在我面前的一个问题是,我该如何去读取数据源,数据源储存的形式是什么?是文本文件还是数据库?
文本文件说实话,不太好实现,而且不规范,正常逻辑数据应该储存在数据库。
但是我现在总不能去装个数据库吧?再写DAO层查询接口?这不现实。
没办法,只能自己简单模拟下数据库操作了!
表结构都是一行一行的数据,那就用List。每行数据(节点)不能只有主键,还要有父节点的外键,因为题目要求也给出了数据是具有指向关系的 。
如何实现数据的查询呢?当然是用Stream,最简单。
分析到这里,完整的代码已经呼之欲出,请看大屏幕 ↘
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class SiteTree {
public final static String COUNTRY = "国";
public final static String PROVINCE = "省";
public final static String CITY = "市";
private static List<Node> list = initData();
//结合数据库比较好实现,所以简单实现下!
private static class Node{
private int cid; //节点ID
private int pid; //父节点ID
private String level; //国》省》市》县》镇
private String name; //例如:山东省、济南市等具体地名
private List<Node> child = new ArrayList<>(); //下一级节点列表
public Node(int cid, int pid, String level, String name) {
this.cid = cid;
this.pid = pid;
this.level = level;
this.name = name;
}
public int getCid() {
return cid;
}
public int getPid() {
return pid;
}
public String getName() {
return name;
}
public List<Node> getChild() {
return child;
}
@Override
public String toString() {
return "Node{" +
"cid=" + cid +
", pid=" + pid +
", level='" + level + '\'' +
", name='" + name + '\'' +
", child=" + child +
'}';
}
}
/**
* 初始化数据库
* @return
*/
private static List<Node> initData() {
//声明一个根节点
Node GUO = new Node(1,0,SiteTree.COUNTRY,"中国");
//将市级节点放入山东省级节点下
Node QLU = new Node(4,1,SiteTree.PROVINCE, "山东省");
//将省级节点放入国级节点下
Node ZJS = new Node(5,1,SiteTree.PROVINCE,"浙江省");
//山东省下的市级单位
Node JINAN = new Node(2,4,SiteTree.CITY,"济南市");
Node JINING = new Node(3,4,SiteTree.CITY,"济宁市");
//简单数据库实现
List<Node> list = new ArrayList<>();
list.add(GUO);
list.add(JINAN);
list.add(JINING);
list.add(QLU);
list.add(ZJS);
return list;
}
public static void main(String[] args){
System.out.println(child(1));
}
private static Node child(int cid) {
//获取节点
Node node = getTreeNode(cid);
//获取子节点
List<Node> childNodes = getChildNode(cid);
//遍历子节点
for (Node child : childNodes){
Node n = child(child.getCid());//递归
node.getChild().add(n);
}
return node;
}
private static Node getTreeNode(int cid) {
return list.stream().filter(node -> {
if (node.getCid() == cid) {
return true;
}
return false;
}).findFirst().get();
}
private static List<Node> getChildNode(int pid) {
return list.stream().filter(node -> {
if (node.getPid() == pid) {
return true;
}
return false;
}).collect(Collectors.toList());
}
}
打印输出:
Node{cid=1, pid=0, level='国', name='中国', child=[
Node{cid=4, pid=1, level='省', name='山东省', child=[
Node{cid=2, pid=4, level='市', name='济南市', child=[]},
Node{cid=3, pid=4, level='市', name='济宁市', child=[]}]},
Node{cid=5, pid=1, level='省', name='浙江省', child=[]}]}
这是我的解答,如果你有更好的解答,欢迎评论分享!
BAT面试题:请使用递归构建N叉树的更多相关文章
- java算法面试题:递归算法题2 第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
package com.swift; public class Digui_Return { public static void main(String[] args) { /* * 递归算法题2 ...
- 笔记 BAT 面试题 及部分答案
题目出自:https://www.jianshu.com/p/c70989bd5f29本文出自 AWeiLoveAndroid的博客 2018年2月20日星期二 随笔 笔记 BAT 面试题 一.jav ...
- 猫哥网络编程系列:详解 BAT 面试题
从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...
- c++ 之面试题(3)数组递归查找
题目描述 1. 给定严格升序(没有相等元素)的数组a,元素个数为cnt, 查找num在数组中的位置序号(以0位起始). 如果没找到则返回: 比num小且最靠近的元素位置序号. 若所有元素均大于num则 ...
- 刷完500道BAT面试题,我能去面试大厂了吗?
面试之前先刷几篇面经,或者做几道热门面试题,想必是大家很熟悉的一种复习方式了,就像我们当年经常做五年高考三年模拟一样.但是可不要把面试题和面经当成你的主要复习方式,它只是锦上添花,绝非雪中送炭! 壹面 ...
- 给1~3年iOS开发 经验朋友们的一些建议(附BAT面试题)
前言 由于笔者是做 iOS 开发的,因此本文也仅对做 iOS 的同行们有针对性,其他方向仅供参考. 1,如果你: 1~3年左右工作经验,本科,非计算机相关科班出生,学校又比较一般. 实习企业不理想没有 ...
- 最强Java并发编程详解:知识点梳理,BAT面试题等
本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
- BAT笔试试题常见试题总结含答案(持续更新。。。)
(1)试题例如以下: class A { int a; short b; int c; char d; }; class B { double a; short b; int c; char d; } ...
- 【BAT面试题系列】面试官:你了解乐观锁和悲观锁吗?
前言 乐观锁和悲观锁问题,是出现频率比较高的面试题.本文将由浅入深,逐步介绍它们的基本概念.实现方式(含实例).适用场景,以及可能遇到的面试官追问,希望能够帮助你打动面试官. 目录 一.基本概念 二. ...
随机推荐
- Bootstrap 前端框架 遇到的问题 解决方案
bootstrap实现导航栏的响应式布局,当在小屏幕.手机屏幕浏览时自动折叠隐藏 直接放代码,更容易理解.下次可以套这个代码 <!DOCTYPE html> <html> &l ...
- Docker进阶之七:管理应用程序数据
管理应用程序数据:Volume Docker提供三种不同的方式将数据从宿主机挂载到容器中:volumes,bind mounts和tmpfs. volumes:Docker管理宿主机文件系统的一部分( ...
- .NET运行时中的监测和可观测性
今年5月份的时候研究分布式追踪的问题知道了的拦截方式比较零散, 刚好8月份的时候看到这篇文章,这个文章总结的比较完整.存档了很久,趁今天有空翻译给大家.原文地址,校验:张蘅水 .NET是一个托管运行时 ...
- python ddt数据驱动(简化重复代码)
在接口自动化测试中,往往一个接口的用例需要考虑 正确的.错误的.异常的.边界值等诸多情况,然后你需要写很多个同样代码,参数不同的用例.如果测试接口很多,不但需要写大量的代码,测试数据和代码柔合在一起, ...
- Sql万能分页代码
sql数据库中常用的分页 我做了一个万能的 用的上的小伙伴拿去耍吧 go ----万能分页代码create procedure [dbo].[sp_datapager] @pagesize int, ...
- 关于时间的那些事--PHP、JavaScript、MySQL操作时间
PHP篇 PHP中时间操作单位是秒 一.将时间戳转为普通日期格式 //当前时间戳 time(); //当前时间格式 date("Y-m-d H:i:s",time()); //昨天 ...
- 将传统 WPF 程序迁移到 DotNetCore 3.0
介绍 由于历史原因,基于 Windows 平台存在着大量的基于 .NetFramework 开发的 WPF 和 WinForm 相关程序,如果将这些程序全部基于 DotNetCore 3.0 重写一遍 ...
- web开发布局---传统布局篇
1.传统布局 盒状模型结合 display 属性.float 浮动以及 position 定位属性设计的各式传统布局形式. 2.说再多不如动手实践,下面举三个例子 html 部分代码: <sec ...
- 【土旦】vue项目中 使用 pako.js 解密 gzip加密字符串
前言 今天跟后台对接一个接口,接受到一个加密的值,说是通过gzip加密过的,然后就蒙蔽了, 赶紧上百度找了一下资料,通过一篇文章(原文在底部)发现有个js库可以解密,就下载轻松解密了 实现代码 pok ...
- mysql很有用的语句
1)删除表内所有数据: 再添加数据时,如果设有自动增加的id,那么id也会重置. truncate table 表名; 2)创建结构相同的数据库表 create table 数据库名.新表名 like ...