题目描述
(通过次数8,111 | 提交次数9,900,通过率81.93%)
表:Logs +---------------+---------+ | Column Name | Type | +---------------+---------+ | log_id | int | +---------------+---------+ log_id 是上表的主键。 上表的每一行包含日志表中的一个 log_id 后来一些 ID 从Logs表中删除。编写一个 SQL 查询得到Logs表中的连续区间的开始数字和结束数字。 将查询表按照 start_id排序。 查询结果格式如下面的例子。 示例 1: 输入: Logs 表: +------------+ | log_id | +------------+ | 1 | | 2 | | 3 | | 7 | | 8 | | 10 | +------------+ 输出: +------------+--------------+ | start_id | end_id | +------------+--------------+ | 1 | 3 | | 7 | 8 | | 10 | 10 | +------------+--------------+ 解释: 结果表应包含 Logs 表中的所有区间。 从 1 到 3 在表中。 从 4 到 6 不在表中。 从 7 到 8 在表中。 9 不在表中。 10 在表中。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/find-the-start-and-end-number-of-continuous-ranges
//测试数据 Create table If Not Exists Logs (log_id int); insert into Logs (log_id) values ('1'); insert into Logs (log_id) values ('2'); insert into Logs (log_id) values ('3'); insert into Logs (log_id) values ('7'); insert into Logs (log_id) values ('8'); insert into Logs (log_id) values ('10');
解题思路
解题思路:
从题目描述和高达81.93%的通过率上来看,似乎这道题很简单,其实不然。
这是一道典型的SQL算法题:求连续区间。
算法这东西,说起来很玄乎,实际上就是针对一个或一类问题的计算方法(解决方案)。
而算法能力,又与数学能力挂勾。
关于数学,网上有一句流行说法:友谊会走散,爱情会变淡,困难会让你痛苦,生活会使你屈服……只有数学不会,不会就是不会。
所以,这道题,对于会的小伙伴,很简单;对于不会的小伙伴,很难!甚至难到怀疑人生:这样的结果也可以使用SQL语句计算出来?
不用怀疑,SQL当然可以完成!下面进入正题。
对于求连续区间,有几种常见的方法,都是基于连续区间的特性来进行计算的。
**第一种特性**:一个有序的集市,错位相减,可以得到区间的开始值和结束值;
**第二种特性**:如果一个数字是一个区间的开始值,那么这个数字-1一定不在集合中;相应的,如果一个数字是一个区间的结束值,那么这个数字+1一定不在集合中;
**第三种特性**:一个有序的集合,如果某几个值是连续的,那么这几个值-它的序号一定是相同的;
上面几个特性理解起来比较抽象,这里我就不一一展开解释了。对于求连续区间的问题,过几天我会专门出一篇推文进行详细的解说(*可以关注我的微信公众号阅读:xuesql*)。
下面的参考答案,是基于第三种特性给出的,是SQL写起来最简洁的一种。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select min(a.log_id) start_id, max(a.log_id) end_id from ( select a.log_id, a.log_id - row_number() over(order by a.log_id) rn from Logs a )a group by a.rn;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。