题解 | #最差是第几名(二)#
最差是第几名(二)
https://www.nowcoder.com/practice/165d88474d434597bcd2af8bf72b24f1
#假设每个名次最多1个人,比如有2个A,那么必定有1个A是第1名,有1个A是第2名(综合成绩同分也会按照某一门的成绩分先后),我先算累加数,然后看中位数落在哪个区间,就取哪个区间 /* 分段区间(只统计每一段的数量,不具体陈列)求中位数,运用到中位数的一大特点, 即中位数的排序永远>=总数/2,比如总数为奇数时,中位数序号就是向上取整(总数/2),比如总数为偶数时,中位数序号就是(总数/2,总数/2+1) */ #窗口函数 lag(字段)over()获取字段上一行的值,由此可以构造区间 #累加构造区间右端 /*with s1 as (select * ,sum(number)over( order by a1.grade asc ) as end from (select * from class_grade order by grade asc) as a1) #累加构造区间左端,s1里第一行偏移为null with内 多个as之间记得加逗号,且前面不用加with了,s2将包含class_grade和s1的所有信息 ,s2 as (select s1.grade as grade1 ,ifnull(lag(s1.end)over(),0) as start1 ,s1.end as end1 from s1 ) #人数总和,单独做一个表,因为sum只有一行,后续用笛卡尔积连接 , total as (select sum(number) as total from class_grade ) #三种情况,1.总数为奇数,必定落在某一分段内,因为中位数只有一个 2.总数为偶数,中位数区间两端点都落在同一排序区间内,这一分段对应的排序区间肯定包含了这两端的序号,即只用求左端点所在的排序区间就等于求出两个端点都在的排序区间,比如 1,3,5,1 ,中位数 第五位 第六位在第三个排序区间内 3.总数为偶数,中位数落在相邻的两个分段内,且中位数序号较小的端点(=总数/2)为其所在排序区间的右端点,如 1,4,4,1,则中位数左端点为 4对应的排序区间 (1,5】的序号5,所以"总数/2*就可确认左端点所在排序区间区间,而"总数+1/2"可确认右端点所在排序区间,因为右端点就是左端点的分段往前进一段 select s.grade1 from s2 s cross join total t where ( ceiling(t.total/2) >s.start1 and ceiling(t.total/2) <=s.end1 ) #满足1和2,排序区间都是左开右闭,所以拿序号比较也要左开右闭才能确认在哪个排序区间 or ( ceiling((t.total+1)/2) >s.start1 and ceiling((t.total+1)/2) <=s.end1 ) #满足3,也不会增添多余区间,因为对于2情况,左端点序号加1就是求右端点所在排序区间,性质一样,对于1情况,(total+1)/2相当于+0.5向上取整,再套个celing也一样=ceiling(t.total/2),如果是t.total/2+1不行,对于1情况,其不等于ceiling(t.total/2),例如celing(7/2+1)=5,而celing(7/2)=4*/ with total as (select sum(number)/2 as t3 from class_grade ) , tab as (select a1.grade as grade1 ,sum(number)over(order by grade asc) as t1 ,sum(number)over(order by grade desc) as t2 from (select * from class_grade order by grade asc) as a1 ) select a.grade1 from tab a cross join total t where a.t1>=t.t3 and a.t2>=t.t3
搬一下热度一的大神写法核心
首先我们需要知道:当某一数的正序和逆序累计均大于整个序列的数字个数的一半即为中位数
比如:
A A B B C C D D
1 2 3 4 5 6 7 8
8 7 6 5 4 3 2 1
那么上面的4,5以及5,4就是中位数,如果是奇数的话,就只有1个
当成为分段排名时,:当某一分段的正序和逆序累计均大于等于整个序列的数字个数的一半即为中位数
A2个,B3个,C5个,D2个,
正序2,5,10,12
倒序12,10,7,2
正序和12,大于等于6的,为C,D,
逆序和为12,大于等于6的为ABC,所以最后中位数为C