C语言 | Leetcode C语言题解之第381题O(1)时间插入、删除和获取随机元素-允许重复

题目:

题解:

cpp 复制代码
#define DYNAMIC_ARRAY_SIZE 128

typedef struct {
    int *data;
    int size, capacity;
} dynamic_array_t;
dynamic_array_t *dynamic_array_init() {
    dynamic_array_t *da = malloc(sizeof(dynamic_array_t));
    da->size = 0, da->capacity = DYNAMIC_ARRAY_SIZE;
    da->data = malloc(da->capacity * sizeof(int));
    return da;
}
void dynamic_array_destroy(dynamic_array_t *da) {
    free(da->data);
    free(da);
}
int dynamic_array_append(dynamic_array_t *da, int val) {
    if (da->size == da->capacity) da->data = realloc(da->data, (da->capacity += DYNAMIC_ARRAY_SIZE) * sizeof(int));
    da->data[da->size] = val;
    return da->size++;
}
int dynamic_array_random(dynamic_array_t *da) {
    return da->data[rand() % da->size];
}
int dynamic_array_pop(dynamic_array_t *da) {
    return da->data[--da->size];
}
int dynamic_array_size(dynamic_array_t *da) {
    return da->size;
}
void dynamic_array_set(dynamic_array_t *da, int index, int val) {
    da->data[index] = val;
}

typedef struct {
    int index;
    UT_hash_handle hh;
} hash_index_t;
void hash_index_add(hash_index_t **t, int val) {
    hash_index_t *index = malloc(sizeof(hash_index_t));
    index->index        = val;
    HASH_ADD_INT(*t, index, index);
}
int hash_index_pop(hash_index_t **t) {
    int ans             = (*t)->index;
    hash_index_t *index = *t;
    HASH_DEL(*t, index);
    free(index);
    return ans;
}
void hash_index_remove(hash_index_t **t, int val) {
    hash_index_t *index = NULL;
    HASH_FIND_INT(*t, &val, index);
    HASH_DEL(*t, index);
    free(index);
}

typedef struct {
    int key;
    hash_index_t *index_hash;
    UT_hash_handle hh;
} hash_t;
hash_t *hash_new(int key, int val) {
    hash_t *h = malloc(sizeof(hash_t));
    h->key = key, h->index_hash = NULL;

    hash_index_add(&h->index_hash, val);
    return h;
}
void hash_destroy(hash_t *h) {
    for (hash_index_t *cur = h->index_hash; cur; cur = h->index_hash) {
        HASH_DEL(h->index_hash, cur);
        free(cur);
    }
    free(h);
}

typedef struct {
    hash_t *hash;
    dynamic_array_t *array;
} RandomizedCollection;

/** Initialize your data structure here. */

RandomizedCollection *randomizedCollectionCreate() {
    RandomizedCollection *collection = malloc(sizeof(RandomizedCollection));

    collection->hash  = NULL;
    collection->array = dynamic_array_init();

    return collection;
}

/** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
bool randomizedCollectionInsert(RandomizedCollection *collection, int val) {
    hash_t *cur = NULL;

    int index = dynamic_array_append(collection->array, val);
    HASH_FIND_INT(collection->hash, &val, cur);
    if (cur) {
        hash_index_add(&cur->index_hash, index);
        return false;
    } else {
        cur = hash_new(val, index);
        HASH_ADD_INT(collection->hash, key, cur);
        return true;
    }
}

/** Removes a value from the collection. Returns true if the collection contained the specified element. */
bool randomizedCollectionRemove(RandomizedCollection *collection, int val) {
    hash_t *cur = NULL;

    HASH_FIND_INT(collection->hash, &val, cur);
    if (!cur) return false;

    // 获取待移除下标
    int index = hash_index_pop(&cur->index_hash);
    // 获取数组最后一位下标
    int index_remove = dynamic_array_size(collection->array) - 1;
    // 获取数组最后一位数据
    int val_change = dynamic_array_pop(collection->array);

    if (index != index_remove) {
        hash_t *change = NULL;

        // 设置数据新位置
        dynamic_array_set(collection->array, index, val_change);

        // 修改哈希表记录
        HASH_FIND_INT(collection->hash, &val_change, change);
        hash_index_add(&change->index_hash, index);
        hash_index_remove(&change->index_hash, index_remove);
    }

    if (HASH_COUNT(cur->index_hash) == 0) {
        HASH_DEL(collection->hash, cur);
        hash_destroy(cur);
    }

    return true;
}

/** Get a random element from the collection. */
int randomizedCollectionGetRandom(RandomizedCollection *collection) {
    return dynamic_array_random(collection->array);
}

void randomizedCollectionFree(RandomizedCollection *collection) {
    dynamic_array_destroy(collection->array);
    for (hash_t *cur = collection->hash; cur; cur = collection->hash) {
        HASH_DEL(collection->hash, cur);
        hash_destroy(cur);
    }
    free(collection);
}
相关推荐
2301_7951672011 分钟前
玩转Rust高级应用 如何避免对空指针做“解引用”操作,在C/C++ 里面就是未定义行为
c语言·c++·rust
ben9518chen5 小时前
嵌入式Linux C语言程序设计九
linux·c语言
下午见。6 小时前
C语言结构体入门:定义、访问与传参全解析
c语言·笔记·学习
cs麦子7 小时前
C语言--函数(function)
c语言·开发语言
极智-9967 小时前
C语言编译器?【图文详解】Visual Studio安装配置编译运行C语言?C语言编译器下载安装?
c语言·visual studio·c语言编译器·c代码运行·visual studio下载·c编程·c语言下载
是苏浙7 小时前
零基础入门C语言之C语言实现数据结构之顺序表
c语言·开发语言·数据结构
代码雕刻家7 小时前
C语言中关于类型转换不匹配的解决方案
c语言·开发语言·算法
许长安9 小时前
c/c++ static关键字详解
c语言·c++·经验分享·笔记
逐步前行10 小时前
C数据结构--排序算法
c语言·数据结构·排序算法
小安同学iter11 小时前
SQL50+Hot100系列(11.7)
java·算法·leetcode·hot100·sql50