Welcome to Subscribe On Youtube

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.

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.

  • 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
    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;
    
    

All Problems

All Solutions