LeetCode //C - 128. Longest Consecutive Sequence

128. Longest Consecutive Sequence

Given an unsorted array of integers nums , return the length of the longest consecutive elements sequence.

You must write an algorithm that runs in O(n) time.

Example 1:

Input: nums = [100,4,200,1,3,2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

Example 2:

Input: nums = [0,3,7,2,5,8,4,6,0,1]
Output: 9

Constraints:

  • 0 < = n u m s . l e n g t h < = 1 0 5 0 <= nums.length <= 10^5 0<=nums.length<=105
  • − 1 0 9 < = n u m s [ i ] < = 1 0 9 -10^9 <= nums[i] <= 10^9 −109<=nums[i]<=109

From: LeetCode

Link: 128. Longest Consecutive Sequence


Solution:

Ideas:

The idea behind this code is to find the length of the longest consecutive elements sequence in an unsorted array of integers. It does this by leveraging a hash table to achieve O(n) time complexity. Here's a step-by-step explanation of the code:

  1. Hash Table Creation: The code first creates a hash table to efficiently store and search for the numbers in the given array. The hash table is implemented using separate chaining, where each index in the table's array represents a linked list of hash nodes.

  2. Populating the Hash Table: The code iterates through the input array and inserts each number into the hash table. The key for each number is the number itself, and the index is calculated using the absolute value of the number modulo the table's size.

  3. Finding the Longest Consecutive Sequence: The main logic of the code iterates through the input array again, checking for the beginning of a consecutive sequence. It identifies the start of a sequence by looking for a number that doesn't have a predecessor (i.e., there's no (num - 1) in the hash table). Once the start of a sequence is found, it continues to check for consecutive numbers in the sequence, incrementing a counter for each successive number found.

  4. Checking for Consecutive Numbers: To check whether a number is part of a consecutive sequence, the code looks up the number in the hash table using the contains function. This enables efficient O(1) average-time lookups, allowing the code to quickly identify consecutive numbers in the sequence.

  5. Tracking the Longest Sequence: As the code identifies consecutive sequences, it keeps track of the length of the current sequence and updates the length of the longest sequence found so far. Once all numbers have been processed, the length of the longest consecutive sequence is returned.

  6. Memory Cleanup: Finally, the code includes logic to free the dynamically allocated memory for the hash table and its associated linked lists.

Code:
c 复制代码
struct HashNode {
    int key;
    struct HashNode *next;
};

struct HashTable {
    int size;
    struct HashNode **array;
};

struct HashTable* createHashTable(int size) {
    struct HashTable* table = (struct HashTable*)malloc(sizeof(struct HashTable));
    table->size = size;
    table->array = (struct HashNode**)malloc(sizeof(struct HashNode*) * size);
    for (int i = 0; i < size; i++) {
        table->array[i] = NULL;
    }
    return table;
}

void insert(struct HashTable *table, int key) {
    int index = (key < 0 ? -key : key) % table->size;
    struct HashNode *newNode = (struct HashNode*)malloc(sizeof(struct HashNode));
    newNode->key = key;
    newNode->next = table->array[index];
    table->array[index] = newNode;
}

bool contains(struct HashTable *table, int key) {
    int index = (key < 0 ? -key : key) % table->size;
    struct HashNode *current = table->array[index];
    while (current != NULL) {
        if (current->key == key) return true;
        current = current->next;
    }
    return false;
}

int longestConsecutive(int* nums, int numsSize) {
    if (numsSize == 0) return 0;

    struct HashTable *table = createHashTable(numsSize * 2);
    for (int i = 0; i < numsSize; i++) {
        insert(table, nums[i]);
    }

    int longestStreak = 0;
    for (int i = 0; i < numsSize; i++) {
        if (!contains(table, nums[i] - 1)) {
            int currentNum = nums[i];
            int currentStreak = 1;

            while (contains(table, currentNum + 1)) {
                currentNum += 1;
                currentStreak += 1;
            }

            if (currentStreak > longestStreak) {
                longestStreak = currentStreak;
            }
        }
    }

    // Free the allocated memory for the table
    for (int i = 0; i < table->size; i++) {
        struct HashNode* current = table->array[i];
        while (current != NULL) {
            struct HashNode* temp = current;
            current = current->next;
            free(temp);
        }
    }
    free(table->array);
    free(table);

    return longestStreak;
}
相关推荐
艾醒几秒前
大模型原理剖析——突破LLM效率瓶颈:多标记预测(MTP)技术深度解析与实战
算法
智驱力人工智能几秒前
森林防火无人机火焰监测系统 构建“天空地”一体化智能防火体系 无人机火焰检测,支持红色火焰检测 城市高层建筑无人机火焰识别
人工智能·深度学习·opencv·算法·目标检测·无人机·边缘计算
多米Domi0111 分钟前
0x3f第12天 0-1背包
python·算法·leetcode·动态规划
Bruce_kaizy7 分钟前
c++图论————最短路之Floyd&Dijkstra算法
c++·算法·图论
黎雁·泠崖14 分钟前
指针收官篇:sizeof/strlen + 指针运算笔试考点全梳理
c语言·开发语言
WBluuue17 分钟前
AtCoder Beginner Contest 437(ABCDEF)
c++·算法
郝学胜-神的一滴17 分钟前
Linux 下循环创建多线程:深入解析与实践指南
linux·服务器·c++·程序人生·算法·设计模式
lingran__22 分钟前
数据在内存中的存储详解(C语言拓展版)
c语言·开发语言
superman超哥23 分钟前
仓颉语言中异常处理入门的深度剖析与工程实践
c语言·开发语言·c++·python·仓颉
ss27334 分钟前
线程池优雅关闭:线程池生命周期管理:四种关闭策略的实战对比
java·jvm·算法