Skip to content

feat: add solutions to lc problem: No.3617 #4570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import pandas as pd
from datetime import timedelta


def find_study_spiral_pattern(
students: pd.DataFrame, study_sessions: pd.DataFrame
) -> pd.DataFrame:
# Convert session_date to datetime
study_sessions["session_date"] = pd.to_datetime(study_sessions["session_date"])

result = []

# Group study sessions by student
for student_id, group in study_sessions.groupby("student_id"):
# Sort sessions by date
group = group.sort_values("session_date").reset_index(drop=True)

temp = [] # Holds current contiguous segment
last_date = None

for idx, row in group.iterrows():
if not temp:
temp.append(row)
else:
delta = (row["session_date"] - last_date).days
if delta <= 2:
temp.append(row)
else:
# Check the previous contiguous segment
if len(temp) >= 6:
_check_pattern(student_id, temp, result)
temp = [row]
last_date = row["session_date"]

# Check the final segment
if len(temp) >= 6:
_check_pattern(student_id, temp, result)

# Build result DataFrame
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",
]
)

# Join with students table to get name and major
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)

# Try possible cycle lengths from 3 up to half of the sequence
for cycle_len in range(3, n // 2 + 1):
if n % cycle_len != 0:
continue

# Extract the first cycle
first_cycle = subjects[:cycle_len]
is_pattern = True

# Compare each following cycle with the first
for i in range(1, n // cycle_len):
if subjects[i * cycle_len : (i + 1) * cycle_len] != first_cycle:
is_pattern = False
break

# If a repeated cycle is detected, store the result
if is_pattern:
result.append(
{
"student_id": student_id,
"cycle_length": cycle_len,
"total_study_hours": hours,
}
)
break # Stop at the first valid cycle found
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Write your MySQL query statement below
WITH
ranked_sessions AS (
SELECT
s.student_id,
ss.session_date,
ss.subject,
ss.hours_studied,
ROW_NUMBER() OVER (
PARTITION BY s.student_id
ORDER BY ss.session_date
) AS rn
FROM
study_sessions ss
JOIN students s ON s.student_id = ss.student_id
),
grouped_sessions AS (
SELECT
*,
DATEDIFF(
session_date,
LAG(session_date) OVER (
PARTITION BY student_id
ORDER BY session_date
)
) AS date_diff
FROM ranked_sessions
),
session_groups AS (
SELECT
*,
SUM(
CASE
WHEN date_diff > 2
OR date_diff IS NULL THEN 1
ELSE 0
END
) OVER (
PARTITION BY student_id
ORDER BY session_date
) AS group_id
FROM grouped_sessions
),
valid_sequences AS (
SELECT
student_id,
group_id,
COUNT(*) AS session_count,
GROUP_CONCAT(subject ORDER BY session_date) AS subject_sequence,
SUM(hours_studied) AS total_hours
FROM session_groups
GROUP BY student_id, group_id
HAVING session_count >= 6
),
pattern_detected AS (
SELECT
vs.student_id,
vs.total_hours,
vs.subject_sequence,
COUNT(
DISTINCT
SUBSTRING_INDEX(SUBSTRING_INDEX(subject_sequence, ',', n), ',', -1)
) AS cycle_length
FROM
valid_sequences vs
JOIN (
SELECT a.N + b.N * 10 + 1 AS n
FROM
(
SELECT 0 AS N
UNION
SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6
UNION
SELECT 7
UNION
SELECT 8
UNION
SELECT 9
) a,
(
SELECT 0 AS N
UNION
SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6
UNION
SELECT 7
UNION
SELECT 8
UNION
SELECT 9
) b
) nums
ON n <= 10
WHERE
-- Check if the sequence repeats every `k` items, for some `k >= 3` and divides session_count exactly
-- We simplify by checking the start and middle halves are equal
LENGTH(subject_sequence) > 0
AND LOCATE(',', subject_sequence) > 0
AND (
-- For cycle length 3:
subject_sequence LIKE CONCAT(
SUBSTRING_INDEX(subject_sequence, ',', 3),
',',
SUBSTRING_INDEX(SUBSTRING_INDEX(subject_sequence, ',', 6), ',', -3),
'%'
)
OR subject_sequence LIKE CONCAT(
-- For cycle length 4:
SUBSTRING_INDEX(subject_sequence, ',', 4),
',',
SUBSTRING_INDEX(SUBSTRING_INDEX(subject_sequence, ',', 8), ',', -4),
'%'
)
)
GROUP BY vs.student_id, vs.total_hours, vs.subject_sequence
),
final_output AS (
SELECT
s.student_id,
s.student_name,
s.major,
pd.cycle_length,
pd.total_hours AS total_study_hours
FROM
pattern_detected pd
JOIN students s ON s.student_id = pd.student_id
WHERE pd.cycle_length >= 3
)
SELECT *
FROM final_output
ORDER BY cycle_length DESC, total_study_hours DESC;
1 change: 1 addition & 0 deletions solution/DATABASE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@
| 3586 | [寻找 COVID 康复患者](/solution/3500-3599/3586.Find%20COVID%20Recovery%20Patients/README.md) | `数据库` | 中等 | |
| 3601 | [寻找燃油效率提升的驾驶员](/solution/3600-3699/3601.Find%20Drivers%20with%20Improved%20Fuel%20Efficiency/README.md) | `数据库` | 中等 | |
| 3611 | [查找超预订员工](/solution/3600-3699/3611.Find%20Overbooked%20Employees/README.md) | | 中等 | |
| 3617 | [Find Students with Study Spiral Pattern](/solution/3600-3699/3617.Find%20Students%20with%20Study%20Spiral%20Pattern/README.md) | | 困难 | |

## 版权

Expand Down
1 change: 1 addition & 0 deletions solution/DATABASE_README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ Press <kbd>Control</kbd> + <kbd>F</kbd>(or <kbd>Command</kbd> + <kbd>F</kbd> on
| 3586 | [Find COVID Recovery Patients](/solution/3500-3599/3586.Find%20COVID%20Recovery%20Patients/README_EN.md) | `Database` | Medium | |
| 3601 | [Find Drivers with Improved Fuel Efficiency](/solution/3600-3699/3601.Find%20Drivers%20with%20Improved%20Fuel%20Efficiency/README_EN.md) | `Database` | Medium | |
| 3611 | [Find Overbooked Employees](/solution/3600-3699/3611.Find%20Overbooked%20Employees/README_EN.md) | | Medium | |
| 3617 | [Find Students with Study Spiral Pattern](/solution/3600-3699/3617.Find%20Students%20with%20Study%20Spiral%20Pattern/README_EN.md) | | Hard | |

## Copyright

Expand Down
1 change: 1 addition & 0 deletions solution/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3627,6 +3627,7 @@
| 3614 | [用特殊操作处理字符串 II](/solution/3600-3699/3614.Process%20String%20with%20Special%20Operations%20II/README.md) | | 困难 | 第 458 场周赛 |
| 3615 | [图中的最长回文路径](/solution/3600-3699/3615.Longest%20Palindromic%20Path%20in%20Graph/README.md) | | 困难 | 第 458 场周赛 |
| 3616 | [Number of Student Replacements](/solution/3600-3699/3616.Number%20of%20Student%20Replacements/README.md) | | 中等 | 🔒 |
| 3617 | [Find Students with Study Spiral Pattern](/solution/3600-3699/3617.Find%20Students%20with%20Study%20Spiral%20Pattern/README.md) | | 困难 | |

## 版权

Expand Down
1 change: 1 addition & 0 deletions solution/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3625,6 +3625,7 @@ Press <kbd>Control</kbd> + <kbd>F</kbd>(or <kbd>Command</kbd> + <kbd>F</kbd> on
| 3614 | [Process String with Special Operations II](/solution/3600-3699/3614.Process%20String%20with%20Special%20Operations%20II/README_EN.md) | | Hard | Weekly Contest 458 |
| 3615 | [Longest Palindromic Path in Graph](/solution/3600-3699/3615.Longest%20Palindromic%20Path%20in%20Graph/README_EN.md) | | Hard | Weekly Contest 458 |
| 3616 | [Number of Student Replacements](/solution/3600-3699/3616.Number%20of%20Student%20Replacements/README_EN.md) | | Medium | 🔒 |
| 3617 | [Find Students with Study Spiral Pattern](/solution/3600-3699/3617.Find%20Students%20with%20Study%20Spiral%20Pattern/README_EN.md) | | Hard | |

## Copyright

Expand Down