งูต้นฉบับต่อแผ่นทางเดินเลขที่ไร้ตัวอักษรจากชิ้นเริ่มต้น โดยกองชิ้นซ้ำถูกวางด้านข้าง

LeetCode #128 Longest Consecutive Sequence: เริ่มนับเฉพาะหัวแถว

พี่โชว์Engineering

Longest Consecutive Sequence ถามความยาวลำดับจำนวนเต็มติดกันที่ยาวที่สุดโดย input ไม่เรียง และตั้งเป้าเวลา O(n) เคล็ดลับคือไม่เริ่มเดินจากทุกเลข แต่เริ่มเฉพาะเลขที่ไม่มี value - 1 อยู่ในชุดครับ

วิธี 1: Sort สำเนา

เรียงแล้วเดินครั้งเดียว ข้าม duplicate และ reset เมื่อเกิดช่องว่าง เวลา O(n log n) พื้นที่ขึ้นกับการ sort; ในโค้ดนี้สร้างสำเนาจึงเป็น O(n) อ่านง่ายและเหมาะเมื่อข้อมูลต้องเรียงต่ออยู่แล้ว

วิธี 2: Hash Set (default)

สร้าง set เพื่อตัด duplicate จากนั้นเลขใดไม่มี predecessor ถือเป็นหัวแถว เดินต่อ +1 จนขาด แม้มี while ซ้อน แต่แต่ละเลขถูกเดินในแถวของตัวเองครั้งเดียว จึงเฉลี่ย O(n)

from __future__ import annotations

import unittest


def sorting(nums: list[int]) -> int:
    if not nums:
        return 0
    ordered = sorted(nums)
    best = current = 1
    for before, value in zip(ordered, ordered[1:]):
        if value == before:
            continue
        current = current + 1 if value == before + 1 else 1
        best = max(best, current)
    return best


def hash_set(nums: list[int]) -> int:
    values = set(nums)
    best = 0
    for value in values:
        if value - 1 in values:
            continue
        length = 1
        while value + length in values:
            length += 1
        best = max(best, length)
    return best


class ConsecutiveTests(unittest.TestCase):
    def test_both_methods(self):
        cases = [
            ([], 0),
            ([100, 4, 200, 1, 3, 2], 4),
            ([0, 3, 7, 2, 5, 8, 4, 6, 0, 1], 9),
            ([-2, -1, -1, 0, 2], 3),
        ]
        for solve in (sorting, hash_set):
            for nums, expected in cases:
                self.assertEqual(solve(nums), expected)


if __name__ == "__main__":
    unittest.main()

Decision table

เงื่อนไขSortHash set
เวลาO(n log n)เฉลี่ย O(n)
พื้นที่ในตัวอย่างO(n)O(n)
duplicateต้องข้ามถูกตัดอัตโนมัติ
รักษา inputใช่ เพราะ sort สำเนาใช่
worst-case hashไม่เกี่ยวขึ้นกับ hash implementation
input ต้องเรียงต่อเหมาะไม่จำเป็น

Recap

  • คืน 0 สำหรับ input ว่าง
  • ตัดหรือข้าม duplicate
  • เริ่มเดิน hash set เฉพาะเมื่อไม่มี predecessor
  • ใช้ sort เมื่อผลลัพธ์เรียงมีประโยชน์ต่อขั้นถัดไป