Talentd
FleetCode
Make and follow sheets.Sign in

Find Students with Study Spiral Pattern solution and explanation

Hard8 min read23.1% acceptanceUpdated 16 Oct 2026
Leetcode HARD 3617 - Find Students with Study Spiral Pattern | Everyday Data Science - SQL PlaylistEveryday Data Science · 22:03 · 744 viewsWatch on YouTube
2 more videos on this problem
  1. Leetcode HARD 3617 - Find Students with Study Spiral Pattern | Everyday Data Science - SQL PlaylistEveryday Data Science · 22:03 · 744 views
  2. 😧Cracking Hard SQL: Study Spiral Pattern (LeetCode 3617) - Part 1Vivek The Analyst · 15:10 · 161 views
  3. Find Students with Study Spiral Pattern – LeetCode 3617 Explained (PostgreSQL Tutorial)Sumanshu Nankana · 1:12:43 · 156 views

The problem

Table: students

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| student_id   | int     |
| student_name | varchar |
| major        | varchar |
+--------------+---------+
student_id is the unique identifier for this table.
Each row contains information about a student and their academic major.

Table: study_sessions

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| session_id    | int     |
| student_id    | int     |
| subject       | varchar |
| session_date  | date    |
| hours_studied | decimal |
+---------------+---------+
session_id is the unique identifier for this table.
Each row represents a study session by a student for a specific subject.

Write a solution to find students who follow the Study Spiral Pattern - students who consistently study multiple subjects in a rotating cycle.

  • A Study Spiral Pattern means a student studies at least 3 different subjects in a repeating sequence
  • The pattern must repeat for at least 2 complete cycles (minimum 6 study sessions)
  • Sessions must be consecutive dates with no gaps longer than 2 days between sessions
  • Calculate the cycle length (number of different subjects in the pattern)
  • Calculate the total study hours across all sessions in the pattern
  • Only include students with cycle length of at least 3 subjects

Return the result table ordered by cycle length in descending order, then by total study hours in descending order.

The result format is in the following example.

Example:

Input:

students table:

+------------+--------------+------------------+
| student_id | student_name | major            |
+------------+--------------+------------------+
| 1          | Alice Chen   | Computer Science |
| 2          | Bob Johnson  | Mathematics      |
| 3          | Carol Davis  | Physics          |
| 4          | David Wilson | Chemistry        |
| 5          | Emma Brown   | Biology          |
+------------+--------------+------------------+

study_sessions table:

+------------+------------+------------+--------------+---------------+
| session_id | student_id | subject    | session_date | hours_studied |
+------------+------------+------------+--------------+---------------+
| 1          | 1          | Math       | 2023-10-01   | 2.5           |
| 2          | 1          | Physics    | 2023-10-02   | 3.0           |
| 3          | 1          | Chemistry  | 2023-10-03   | 2.0           |
| 4          | 1          | Math       | 2023-10-04   | 2.5           |
| 5          | 1          | Physics    | 2023-10-05   | 3.0           |
| 6          | 1          | Chemistry  | 2023-10-06   | 2.0           |
| 7          | 2          | Algebra    | 2023-10-01   | 4.0           |
| 8          | 2          | Calculus   | 2023-10-02   | 3.5           |
| 9          | 2          | Statistics | 2023-10-03   | 2.5           |
| 10         | 2          | Geometry   | 2023-10-04   | 3.0           |
| 11         | 2          | Algebra    | 2023-10-05   | 4.0           |
| 12         | 2          | Calculus   | 2023-10-06   | 3.5           |
| 13         | 2          | Statistics | 2023-10-07   | 2.5           |
| 14         | 2          | Geometry   | 2023-10-08   | 3.0           |
| 15         | 3          | Biology    | 2023-10-01   | 2.0           |
| 16         | 3          | Chemistry  | 2023-10-02   | 2.5           |
| 17         | 3          | Biology    | 2023-10-03   | 2.0           |
| 18         | 3          | Chemistry  | 2023-10-04   | 2.5           |
| 19         | 4          | Organic    | 2023-10-01   | 3.0           |
| 20         | 4          | Physical   | 2023-10-05   | 2.5           |
+------------+------------+------------+--------------+---------------+

Output:

+------------+--------------+------------------+--------------+-------------------+
| student_id | student_name | major            | cycle_length | total_study_hours |
+------------+--------------+------------------+--------------+-------------------+
| 2          | Bob Johnson  | Mathematics      | 4            | 26.0              |
| 1          | Alice Chen   | Computer Science | 3            | 15.0              |
+------------+--------------+------------------+--------------+-------------------+

Explanation:

  • Alice Chen (student_id = 1):
    • Study sequence: Math → Physics → Chemistry → Math → Physics → Chemistry
    • Pattern: 3 subjects (Math, Physics, Chemistry) repeating for 2 complete cycles
    • Consecutive dates: Oct 1-6 with no gaps > 2 days
    • Cycle length: 3 subjects
    • Total hours: 2.5 + 3.0 + 2.0 + 2.5 + 3.0 + 2.0 = 15.0 hours
  • Bob Johnson (student_id = 2):
    • Study sequence: Algebra → Calculus → Statistics → Geometry → Algebra → Calculus → Statistics → Geometry
    • Pattern: 4 subjects (Algebra, Calculus, Statistics, Geometry) repeating for 2 complete cycles
    • Consecutive dates: Oct 1-8 with no gaps > 2 days
    • Cycle length: 4 subjects
    • Total hours: 4.0 + 3.5 + 2.5 + 3.0 + 4.0 + 3.5 + 2.5 + 3.0 = 26.0 hours
  • Students not included:
    • Carol Davis (student_id = 3): Only 2 subjects (Biology, Chemistry) - doesn't meet minimum 3 subjects requirement
    • David Wilson (student_id = 4): Only 2 study sessions with a 4-day gap - doesn't meet consecutive dates requirement
    • Emma Brown (student_id = 5): No study sessions recorded

The result table is ordered by cycle_length in descending order, then by total_study_hours in descending order.

Approach overview

Problem Overview: You get a table of student study records. For each student, you need to order the records by time and check whether consecutive entries follow the spiral pattern defined in the problem. Return the students who match it.

Approach 1: Self-Join on Consecutive Rows (O(n^2) time, O(n) space)

Join the table to itself on student_id and match each record with the next record for the same student using a timestamp or sequence comparison. Filter the joined rows against the spiral condition, then keep the students with matches. This is easy to write and shows you understand how to relate rows to their neighbors. The cost is that the join can grow quadratically when a student has many records, so it does not scale well on large logs.

Approach 2: Window Functions with LAG or LEAD (O(n log n) time, O(n) space)

Partition the data by student_id and order each partition by the time column. Use LAG or LEAD to pull the previous or next value into the same row, then evaluate the spiral condition in a single pass per partition. The sort inside each partition dominates the cost, so the total is O(n log n). Prefer this approach for SQL because the database engine handles partitioning and ordering efficiently, and the logic stays in one query without a self-join.

Approach 3: Pandas groupby with shift (O(n log n) time, O(n) space)

In Pandas, sort the DataFrame by student and time, then call groupby('student_id') followed by shift() to create the lagged columns. Compute a boolean mask for the spiral condition with vectorized comparisons, then filter and deduplicate the student IDs. This matches the SQL window function logic and runs entirely in vectorized operations, which keeps it fast for in-memory data.

Recommended for interviews: Interviewers expect you to name the self-join as a first pass, since it shows you understand row relationships. The window function or shift-based solution shows skill because it removes the join, relies on ordering within partitions, and runs in O(n log n). Write the window function version and explain why the sort is the main cost.

Related reading: database problems and sorting techniques.

Solution

Thinking

Enumerating every divisor of the session list and treating it as the cycle length accepts a block such as A, B, A, C repeated twice with length 4, even though only three subjects appear. The statement defines cycle length as the number of distinct subjects.

The two-day limit applies to every adjacent pair in that student's full date order. One gap longer than two days means the sessions are not one consecutive run, so a later fragment is not reported on its own. Sessions on the same date are ordered by session_id.

When the whole record stays within that limit, the cycle length k is the number of distinct subjects. At least two complete cycles require k\ge 3, at least 2k sessions, and a length divisible by k.

Each session is then compared with the subject at the same offset in the first cycle. When the whole record repeats those k subjects, record k and the total hours, join the student table, and sort by cycle length and hours, both descending.

# Write your MySQL query statement below
WITH
    ranked_sessions AS (
        SELECT
            ss.student_id,
            ss.session_id,
            ss.session_date,
            ss.subject,
            ss.hours_studied,
            DATEDIFF(
                ss.session_date,
                LAG(ss.session_date) OVER (
                    PARTITION BY ss.student_id
                    ORDER BY ss.session_date, ss.session_id
                )
            ) AS date_diff,
            ROW_NUMBER() OVER (
                PARTITION BY ss.student_id
                ORDER BY ss.session_date, ss.session_id
            ) AS session_index
        FROM study_sessions ss
    ),
    contiguous_students AS (
        SELECT student_id
        FROM ranked_sessions
        GROUP BY student_id
        HAVING
            SUM(
                CASE
                    WHEN date_diff > 2 THEN 1
                    ELSE 0
                END
            ) = 0
    ),
    student_stats AS (
        SELECT
            r.student_id,
            COUNT(*) AS session_count,
            COUNT(DISTINCT r.subject) AS cycle_length,
            SUM(r.hours_studied) AS total_hours
        FROM
            ranked_sessions r
            JOIN contiguous_students c ON c.student_id = r.student_id
        GROUP BY r.student_id
        HAVING
            cycle_length >= 3
            AND session_count >= cycle_length * 2
            AND session_count % cycle_length = 0
    )
SELECT
    s.student_id,
    s.student_name,
    s.major,
    st.cycle_length,
    st.total_hours AS total_study_hours
FROM
    student_stats st
    JOIN students s ON s.student_id = st.student_id
WHERE
    NOT EXISTS (
        SELECT 1
        FROM
            ranked_sessions cur
            JOIN ranked_sessions cyc
                ON cyc.student_id = cur.student_id
                AND cyc.session_index = (cur.session_index - 1) % st.cycle_length + 1
        WHERE cur.student_id = st.student_id AND NOT (cur.subject <=> cyc.subject)
    )
ORDER BY st.cycle_length DESC, st.total_hours DESC;
import pandas as pd


def find_study_spiral_pattern(
    students: pd.DataFrame, study_sessions: pd.DataFrame
) -> pd.DataFrame:
    study_sessions = study_sessions.copy()
    study_sessions["session_date"] = pd.to_datetime(study_sessions["session_date"])

    result = []

    for student_id, group in study_sessions.groupby("student_id"):
        group = group.sort_values(["session_date", "session_id"]).reset_index(drop=True)
        # One gap longer than two days breaks the whole record. A later fragment
        # is not a separate spiral.
        if len(group) >= 2:
            gaps = group["session_date"].diff().dt.days.iloc[1:]
            if (gaps > 2).any():
                continue
        _check_pattern(student_id, [row for _, row in group.iterrows()], result)

    df_result = pd.DataFrame(
        result, columns=["student_id", "cycle_length", "total_study_hours"]
    )

    if df_result.empty:
        return pd.DataFrame(
            columns=[
                "student_id",
                "student_name",
                "major",
                "cycle_length",
                "total_study_hours",
            ]
        )

    df_result = df_result.merge(students, on="student_id")
    df_result = df_result[
        ["student_id", "student_name", "major", "cycle_length", "total_study_hours"]
    ]

    return df_result.sort_values(
        by=["cycle_length", "total_study_hours"], ascending=[False, False]
    ).reset_index(drop=True)


def _check_pattern(student_id, sessions, result):
    subjects = [row["subject"] for row in sessions]
    hours = sum(row["hours_studied"] for row in sessions)

    n = len(subjects)
    # Cycle length is the number of distinct subjects, not an arbitrary divisor.
    cycle_len = len(set(subjects))
    if cycle_len < 3 or n < cycle_len * 2 or n % cycle_len != 0:
        return

    first_cycle = subjects[:cycle_len]
    if subjects != first_cycle * (n // cycle_len):
        return

    result.append(
        {
            "student_id": student_id,
            "cycle_length": cycle_len,
            "total_study_hours": hours,
        }
    )
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Self-Join on Consecutive RowsO(n^2)O(n)Small tables or when window functions are unavailable
Window Functions (LAG/LEAD)O(n log n)O(n)General SQL case and interview answer
Pandas groupby + shiftO(n log n)O(n)In-memory data in Python workflows

Frequently asked questions

Find Students with Study Spiral Pattern Python solution?

In Python, load the records into a Pandas DataFrame, sort by student and time, use groupby on student_id with shift to create lagged columns, build a boolean mask for the spiral condition, and return the unique matching student IDs.

Is Find Students with Study Spiral Pattern easy or hard?

It is rated Hard on FleetCode with a 23.1% acceptance rate. The difficulty comes from correctly ordering the records within each student and encoding the spiral condition across consecutive rows, not from the amount of code.

How to solve Find Students with Study Spiral Pattern in O(n log n)?

Partition the table by student_id, order each partition by the time column, and apply LAG or LEAD to compare each row with its previous or next row. Filter rows that match the spiral condition and return the distinct student IDs.

What is the best approach for Find Students with Study Spiral Pattern?

The best approach is to use window functions (LAG or LEAD) partitioned by student and ordered by time in SQL, or the equivalent groupby with shift in Pandas. This checks each record against its neighbor in a single pass per student without a self-join.

What data structure is used in Find Students with Study Spiral Pattern?

This is a database problem, so the main structure is the table itself, processed with window functions or DataFrame operations. No custom data structure like a hash map or heap is required.

What is the time complexity of Find Students with Study Spiral Pattern?

The optimal solution runs in O(n log n) time because the records must be sorted by time within each student partition. The space complexity is O(n) for the intermediate results.

Is Find Students with Study Spiral Pattern asked at Google, Amazon, or Meta?

The platform does not list company tags for this problem, so there is no verified data on which companies ask it. Check recent interview reports on company-specific forums before you plan around it.

Comments

Now write it yourselfClose this page and solve Find Students with Study Spiral Pattern in the editor, without looking.
Practise Find Students with Study Spiral Pattern