Leecode 连续出现的数字

原题

编写一个 SQL 查询,查找所有至少连续出现三次的数字。

+----+-----+
| Id | Num |
+----+-----+
| 1  |  1  |
| 2  |  1  |
| 3  |  1  |
| 4  |  2  |
| 5  |  1  |
| 6  |  2  |
| 7  |  2  |
+----+-----+

例如,给定上面的 Logs 表, 1 是唯一连续出现至少三次的数字。

+-----------------+
| ConsecutiveNums |
+-----------------+
| 1               |
+-----------------+

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/consecutive-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解1

方法:用 DISTINCTWHERE 语句

连续出现的意味着相同数字的 Id 是连着的,由于这题问的是至少连续出现 3 次,我们使用 Logs 并检查是否有 3 个连续的相同数字。

SELECT *
FROM
    Logs l1,
    Logs l2,
    Logs l3
WHERE
    l1.Id = l2.Id - 1
    AND l2.Id = l3.Id - 1
    AND l1.Num = l2.Num
    AND l2.Num = l3.Num
;

然后我们从上表中选择任意的 Num 获得想要的答案。同时我们需要添加关键字 DISTINCT ,因为如果一个数字连续出现超过 3 次,会返回重复元素。

SELECT DISTINCT
    l1.Num AS ConsecutiveNums
FROM
    Logs l1,
    Logs l2,
    Logs l3
WHERE
    l1.Id = l2.Id - 1
    AND l2.Id = l3.Id - 1
    AND l1.Num = l2.Num
    AND l2.Num = l3.Num
;

题解2

窗口函数lead()完美解决

使用窗口函数的偏差函数完美实现。 可以这样理解:将num复制两列num1和num2,然后num1整体向上移动一行,num2整体向上移动两行,如下 :
在这里插入图片描述
所以只要num=num1=num2即可.

# Write your MySQL query statement below
select distinct num as ConsecutiveNums  from
(
    select num,lead(num,1)over()as num1,lead(num,2)over()as num2 
    from logs
) as c
where c.num = c.num1 and c.num1 = c.num2

题解3

使用变量,不用连多个表,降低时间空间复杂度
pre记录前一个数的值,count,nums记录前一个数的出现次数

IF()表达式用法

select 
    distinct num as ConsecutiveNums
from
(
    select
    num,
    if(@pre=num,@count:=@count+1,@count:=1) as nums,
    @pre:=num
    from logs as l,
        (select @pre:=null,@count:=1)as pc
) as n
where nums>=3

猜你喜欢

转载自blog.csdn.net/weixin_42072754/article/details/109385106
今日推荐