0Pricing
Coding Interview Prep · Pelajaran

Rangkaian Terpanjang per Pengguna

Menghitung panjang maksimum rangkaian berturut-turut dalam setiap kelompok.

Rangkaian Terpanjang per Pengguna adalah pelajaran Coding Interview Prep gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Coding Interview Prep, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Coding Interview Prep mencakup 4 pelajaran total.

Pertanyaannya

Pertanyaan lanjutan yang sering muncul setelah deteksi hari berurutan: "Untuk setiap pengguna, berapa rentetan terpanjang dari hari-hari aktif yang berurutan?" Tim produk dan pertumbuhan terus-menerus menanyakannya untuk mengukur keterlibatan.

Anda sudah tahu cara mengidentifikasi setiap rentetan. Langkah barunya adalah menemukan panjang maksimum rentetan per pengguna dan, sering kali, mengembalikan tanggal rentetan terbaik tersebut. Pelajaran ini dibangun langsung di atas kerangka celah dan kelompok.

Mengingat Kembali Pembentuk Kelompok

Dari pelajaran sebelumnya, pengelompokan per rentetan menggunakan login_date - ROW_NUMBER() sebagai jangkar kelompok. Setiap pengguna dapat memiliki beberapa kelompok; pertama-tama kita akan menghitung satu baris per kelompok, lalu meringkasnya menjadi satu baris per pengguna.

Ingat rencana dua lapis ini: pertama bangun kelompok, lalu lakukan agregasi pada kelompok tersebut.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
)
SELECT user_id, login_date - rn AS grp
FROM numbered;

Satu Baris per Kelompok

Ringkas setiap kelompok menjadi satu baris rangkuman yang memuat panjang dan rentang tanggalnya. Kelompokkan berdasarkan pengguna dan jangkar, lalu hitung metriknya.

Kita menamai CTE ini islands agar lapisan berikutnya dapat membacanya dengan rapi.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
),
islands AS (
  SELECT user_id,
    MIN(login_date) AS streak_start,
    MAX(login_date) AS streak_end,
    COUNT(*)        AS streak_len
  FROM numbered
  GROUP BY user_id, login_date - rn
)
SELECT * FROM islands;

Jawaban Sederhana: Panjang MAX

Jika pewawancara hanya menginginkan panjangnya, langkah terakhir cukup ditulis dalam satu baris: kelompokkan kelompok berdasarkan pengguna dan ambil panjang maksimum.

Inilah jawaban paling ringkas jika tanggal awal dan akhir tidak diperlukan.

-- ...numbered and islands CTEs as before...
SELECT
  user_id,
  MAX(streak_len) AS longest_streak
FROM islands
GROUP BY user_id
ORDER BY user_id;

Mengembalikan Tanggal Juga

Sering kali pewawancara menambahkan: "dan tampilkan kapan rentetan itu terjadi." MAX biasa tidak dapat memberi tahu kelompok mana yang menjadi pemenang. Anda perlu memberi peringkat pada kelompok dalam setiap pengguna dan mempertahankan peringkat 1.

Gunakan ROW_NUMBER yang diurutkan berdasarkan panjang secara menurun agar rentetan terbaik setiap pengguna mendapat peringkat 1. Tambahkan penentu seri agar hasil seri diselesaikan secara deterministik.

ROW_NUMBER() OVER (
  PARTITION BY user_id
  ORDER BY streak_len DESC, streak_start ASC
) AS rnk

Memberi Peringkat dan Menyaring

Bungkus pemberian peringkat dalam CTE, lalu saring menggunakan rnk = 1. Anda tidak dapat menyaring fungsi jendela secara langsung dalam WHERE, sehingga lapisan tambahan ini wajib digunakan.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
),
islands AS (
  SELECT user_id,
    MIN(login_date) AS streak_start,
    MAX(login_date) AS streak_end,
    COUNT(*)        AS streak_len
  FROM numbered
  GROUP BY user_id, login_date - rn
),
ranked AS (
  SELECT *,
    ROW_NUMBER() OVER (
      PARTITION BY user_id
      ORDER BY streak_len DESC, streak_start
    ) AS rnk
  FROM islands
)
SELECT user_id, streak_start, streak_end, streak_len
FROM ranked
WHERE rnk = 1;

RANK vs ROW_NUMBER untuk Hasil Seri

Bagaimana jika seorang pengguna memiliki dua rentetan dengan panjang maksimum yang sama dan pewawancara ingin mengembalikan keduanya? Ganti ROW_NUMBER dengan RANK dan pertahankan rnk = 1.

  • ROW_NUMBER — tepat satu pemenang per pengguna (dipilih secara arbitrer saat seri, kecuali Anda menambahkan penentu seri).
  • RANK — semua rentetan terpanjang yang seri memiliki peringkat 1 dan semuanya dipertahankan.

Perjelas perilaku yang diinginkan; hal ini menunjukkan perhatian terhadap kasus khusus.

RANK() OVER (
  PARTITION BY user_id
  ORDER BY streak_len DESC
) AS rnk  -- keep all rnk = 1

Contoh Penerapan

Misalkan pengguna 7 masuk pada 1–4 Jan, lalu 10–11 Jan, kemudian 20–23 Jan. Ada tiga kelompok dengan panjang 4, 2, dan 4. Panjang terbesarnya adalah 4, dan terdapat hasil seri.

  • Dengan ROW_NUMBER + penentu seri streak_start: hanya rentetan 1–4 Jan yang dikembalikan.
  • Dengan RANK: rentetan 1–4 Jan dan 20–23 Jan sama-sama dikembalikan.

Menyatakan hal ini secara langsung menunjukkan bahwa Anda telah mempertimbangkan duplikasi.

Menangani Pengguna Tanpa Riwayat Masuk

Pewawancara mungkin bertanya: "Bagaimana dengan pengguna yang tidak pernah masuk?" Pengguna tersebut tidak memiliki baris di logins, sehingga menghilang dari hasil. Jika mereka harus tetap muncul dengan rentetan 0, gunakan LEFT JOIN pada seluruh tabel users dan COALESCE.

SELECT u.user_id,
  COALESCE(MAX(i.streak_len), 0) AS longest_streak
FROM users u
LEFT JOIN islands i ON i.user_id = u.user_id
GROUP BY u.user_id;

Catatan Kinerja

Pola ini melakukan satu lintasan berurutan pada data, ditambah satu pengelompokan. Agar tetap cepat:

  • Pastikan ada indeks pada (user_id, login_date) agar ORDER BY pada fungsi jendela tidak perlu melakukan pengurutan.
  • Hapus duplikasi sejak awal jika sumber memiliki beberapa peristiwa per hari.
  • Hindari membungkus login_date dalam fungsi pada ORDER BY karena hal itu dapat menghambat penggunaan indeks.

Untuk tabel yang sangat besar, cara ini jauh lebih cepat daripada pendekatan penggabungan tabel dengan dirinya sendiri.

Jawaban Lengkap Wawancara

Berikut kueri lengkap yang telah disempurnakan untuk mengembalikan rentetan terpanjang setiap pengguna beserta tanggalnya — versi yang ditulis di papan tulis.

WITH numbered AS (
  SELECT user_id, login_date,
    ROW_NUMBER() OVER (
      PARTITION BY user_id ORDER BY login_date
    ) AS rn
  FROM logins
),
islands AS (
  SELECT user_id,
    MIN(login_date) AS streak_start,
    MAX(login_date) AS streak_end,
    COUNT(*)        AS streak_len
  FROM numbered
  GROUP BY user_id, login_date - rn
),
ranked AS (
  SELECT *,
    ROW_NUMBER() OVER (
      PARTITION BY user_id
      ORDER BY streak_len DESC, streak_start
    ) AS rnk
  FROM islands
)
SELECT user_id, streak_start, streak_end, streak_len
FROM ranked
WHERE rnk = 1
ORDER BY user_id;

Pemeriksaan Singkat

Pilih alat yang tepat untuk kebutuhan tersebut.

Ringkasan

Untuk menghitung rentetan terpanjang setiap pengguna:

  • Bentuk pulau dengan jangkar login_date - ROW_NUMBER().
  • Ringkas setiap pulau menjadi panjang dan rentang tanggal.
  • Jika hanya memerlukan panjang, gunakan MAX(streak_len) yang dikelompokkan berdasarkan pengguna.
  • Jika tanggal juga diperlukan, urutkan pulau setiap pengguna dan pertahankan peringkat 1 — gunakan RANK untuk menyertakan hasil seri, dan ROW_NUMBER untuk satu pemenang.
  • Gunakan LEFT JOIN pada users untuk menampilkan pengguna dengan rentetan 0.

Berikutnya: mendeteksi N baris berurutan yang memenuhi suatu kondisi.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Rangkaian Terpanjang per Pengguna” gratis?

Ya — teks lengkap “Rangkaian Terpanjang per Pengguna” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Coding Interview Prep, upgrade ke CoddyKit PRO. Kursus Coding Interview Prep mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Rangkaian Terpanjang per Pengguna”?

Menghitung panjang maksimum rangkaian berturut-turut dalam setiap kelompok. Kamu berlatih Coding Interview Prep dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Coding Interview Prep?

Tidak diperlukan pengalaman sebelumnya. Coding Interview Prep di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Rangkaian Terpanjang per Pengguna” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Coding Interview Prep ini?

Ya. Setiap pelajaran Coding Interview Prep menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mendeteksi Hari Kalender yang Berurutan
  2. Rangkaian Terpanjang per Pengguna
  3. N Baris Berturut-turut yang Memenuhi Kondisi
  4. Rangkaian Aktif Saat Ini hingga Hari Ini
← Kembali ke Coding Interview Prep