审题大于作答

请添加图片描述

事情的起因请添加图片描述

力扣传送门

我的解
WITH alls AS(

SELECT a.id,COUNT(1)   AS num FROM (
SELECT c.id,c.p_id FROM Tree c
WHERE c.id NOT IN(SELECT id FROM Tree WHERE p_id IS NULL)
UNION ALL
SELECT d.p_id,d.id FROM Tree d
WHERE d.p_id NOT IN(SELECT id FROM Tree WHERE p_id IS NULL)
)AS a
GROUP BY a.id

UNION
SELECT id,0 FROM Tree WHERE p_id IS NULL 
)

SELECT id,(CASE WHEN num>1 THEN 'Inner' WHEN num=0 THEN 'Root' WHEN num=1 THEN 'Leaf' end ) AS [type] FROM alls
WHERE id IS NOT NULL
我的解注解

写的很复杂,加入了很多不需要的查询,因为从一开始,思路就有问题
1.首先null一定就是根节点
2.没有下级的一定是子节点
3.有上级也有下级的就什么节点也不是,也可以理解为有下级的
可不可以理解为两个列合并,如果是null的就是根节点,
如果出现了2次或者以上那他就是什么节点都不是
如果只出现了一次那它就是子节点
这是我审完题后的注解,但是很明显有重复的因为其实第三点,根节点也可以出现,这就导致我后面写的很复杂,可能会有些小伙伴讲,最后不是写出来了吗,但是不管是玩算法的,还是编程的其实都会追求性能,这么多查询,很明显,是很拖累性能的,而且,如果一开始想错了,容易出现南辕北辙,后期通过代码去补救的话,其实蛮痛苦的

最优解
select distinct a.id,
case when a.p_id is null then 'Root'
when b.id is null then 'Leaf'
else 'Inner' end type
from Tree a
left join Tree b 
on b.p_id=a.id 
最优解注解

1.在p_id列为null的就是根节点
2.id存在p_id不存在的就是子节点
3.同时存在的就是内部节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值