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);
}
相关推荐
一只自律的鸡5 分钟前
C语言项目 天天酷跑(上篇)
c语言·开发语言
冠位观测者1 小时前
【Leetcode 热题 100】124. 二叉树中的最大路径和
数据结构·算法·leetcode
悲伤小伞1 小时前
C++_数据结构_详解二叉搜索树
c语言·数据结构·c++·笔记·算法
m0_675988232 小时前
Leetcode3218. 切蛋糕的最小总开销 I
c++·算法·leetcode·职场和发展
佳心饼干-4 小时前
C语言-09内存管理
c语言·算法
物联网牛七七4 小时前
4、数据结构与算法解析(C语言版)--栈
c语言·栈操作
F-2H7 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
axxy20007 小时前
leetcode之hot100---24两两交换链表中的节点(C++)
c++·leetcode·链表
chenziang17 小时前
leetcode hot100 环形链表2
算法·leetcode·链表
呆呆的猫10 小时前
【LeetCode】227、基本计算器 II
算法·leetcode·职场和发展