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);
}
相关推荐
52Hz1187 分钟前
力扣73.矩阵置零、54.螺旋矩阵、48.旋转图像
python·算法·leetcode·矩阵
iAkuya1 小时前
(leetcode)力扣100 二叉搜索树种第K小的元素(中序遍历||记录子树的节点数)
算法·leetcode·职场和发展
Root_Hacker1 小时前
include文件包含个人笔记及c底层调试
android·linux·服务器·c语言·笔记·安全·php
杨间2 小时前
《排序算法全解析:从基础到优化,一文吃透八大排序!》
c语言·数据结构·排序算法
Remember_9932 小时前
【LeetCode精选算法】滑动窗口专题二
java·开发语言·数据结构·算法·leetcode
你怎么知道我是队长3 小时前
C语言---未定义行为
java·c语言·开发语言
圣保罗的大教堂3 小时前
leetcode 1895. 最大的幻方 中等
leetcode
Remember_9933 小时前
【LeetCode精选算法】滑动窗口专题一
java·数据结构·算法·leetcode·哈希算法
漫随流水4 小时前
leetcode回溯算法(77.组合)
数据结构·算法·leetcode·回溯算法
mjhcsp4 小时前
P14987 全等(mjhcsp)
算法·题解·洛谷