返回介绍

solution / 0100-0199 / 0180.Consecutive Numbers / README_EN

发布于 2024-06-17 01:04:03 字数 4472 浏览 0 评论 0 收藏 0

180. Consecutive Numbers

中文文档

Description

Table: Logs

+-------------+---------+
| Column Name | Type  |
+-------------+---------+
| id      | int   |
| num     | varchar |
+-------------+---------+
In SQL, id is the primary key for this table.
id is an autoincrement column.

 

Find all numbers that appear at least three times consecutively.

Return the result table in any order.

The result format is in the following example.

 

Example 1:

Input: 
Logs table:
+----+-----+
| id | num |
+----+-----+
| 1  | 1   |
| 2  | 1   |
| 3  | 1   |
| 4  | 2   |
| 5  | 1   |
| 6  | 2   |
| 7  | 2   |
+----+-----+
Output: 
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1         |
+-----------------+
Explanation: 1 is the only number that appears consecutively for at least three times.

Solutions

Solution 1: Two Joins

We can use two joins to solve this problem.

First, we perform a self-join with the condition l1.num = l2.num and l1.id = l2.id - 1, so that we can find all numbers that appear at least twice in a row. Then, we perform another self-join with the condition l2.num = l3.num and l2.id = l3.id - 1, so that we can find all numbers that appear at least three times in a row. Finally, we only need to select the distinct l2.num.

import pandas as pd


def consecutive_numbers(logs: pd.DataFrame) -> pd.DataFrame:
  all_the_same = lambda lst: lst.nunique() == 1
  logs["is_consecutive"] = (
    logs["num"].rolling(window=3, center=True, min_periods=3).apply(all_the_same)
  )
  return (
    logs.query("is_consecutive == 1.0")[["num"]]
    .drop_duplicates()
    .rename(columns={"num": "ConsecutiveNums"})
  )
# Write your MySQL query statement below
SELECT DISTINCT l2.num AS ConsecutiveNums
FROM
  Logs AS l1
  JOIN Logs AS l2 ON l1.id = l2.id - 1 AND l1.num = l2.num
  JOIN Logs AS l3 ON l2.id = l3.id - 1 AND l2.num = l3.num;

Solution 2: Window Function

We can use the window functions LAG and LEAD to obtain the num of the previous row and the next row of the current row, and record them in the fields $a$ and $b$, respectively. Finally, we only need to filter out the rows where $a = num$ and $b = num$, which are the numbers that appear at least three times in a row. Note that we need to use the DISTINCT keyword to remove duplicates from the results.

We can also group the numbers by using the IF function to determine whether the num of the current row is equal to the num of the previous row. If they are equal, we set it to $0$, otherwise we set it to $1$. Then, we use the window function SUM to calculate the prefix sum, which is the grouping identifier. Finally, we only need to group by the grouping identifier and filter out the numbers with a row count greater than or equal to $3$ in each group. Similarly, we need to use the DISTINCT keyword to remove duplicates from the results.

# Write your MySQL query statement below
WITH
  T AS (
    SELECT
      *,
      LAG(num) OVER () AS a,
      LEAD(num) OVER () AS b
    FROM Logs
  )
SELECT DISTINCT num AS ConsecutiveNums
FROM T
WHERE a = num AND b = num;

Solution 3

# Write your MySQL query statement below
WITH
  T AS (
    SELECT
      *,
      IF(num = (LAG(num) OVER ()), 0, 1) AS st
    FROM Logs
  ),
  S AS (
    SELECT *, SUM(st) OVER (ORDER BY id) AS p
    FROM T
  )
SELECT DISTINCT num AS ConsecutiveNums
FROM S
GROUP BY p
HAVING COUNT(1) >= 3;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文