C 语言构造hash table 解 LC majority element问题

Leetcode上 majority element这题是 有 时间O(N), 空间O(1)的解的.

https://leetcode.com/problems/majority-element/

用hash table来解则为 时间O(N), 空间O(N). 如果是Java里 用HashMap很方便了. 有位同学问怎么用c语言来构造hash table. 我就随手写了一个:

typedef struct Node {
    int val, count;
} Node;

typedef struct HASH {
    Node *np;
    int size, capacity;
} HASH;

#define N 509

#define HASH_VAL(n) abs((n) % N)

static int ensureCapacity(HASH *hp) 
{
    int size, capacity;
    Node *np;

    size = hp->size;
    capacity = hp->capacity;
    if (size < capacity)
        return 0;
    if (capacity == 0)
        capacity = 8;
    else
        capacity <<= 1;
    np = (Node*)realloc(hp->np, capacity * sizeof(Node));
    if (np == NULL)
        return -1;
    hp->capacity = capacity;
    hp->np = np;
    return 0;
}

static void freeHashTab(HASH htab[], int n)
{
    int i;
    for (i = 0; i < n; i++)
        if (htab[i].np)
            free(htab[i].np);    
}

int majorityElement(int arr[], int n) 
{
    HASH htab[N], *hb;
    int i, j, cur, hval, res;

    memset(htab, 0, N * sizeof(HASH));
    for (i = 0; i < n; i++) {
        cur = arr[i];
        hval = HASH_VAL(cur);
        hb = &htab[hval];
        for (j = 0; j < hb->size; j++)
            if (hb->np[j].val == cur)
                break;
        if (j == hb->size) {
            if (ensureCapacity(hb) == -1)
                goto err;
            hb->np[j].val = cur;
            hb->np[j].count = 1;
            hb->size++; 
        } else {
            hb->np[j].count++;
        }
        if (hb->np[j].count > n / 2) {
            res = hb->np[j].val;
            freeHashTab(htab, N);
            return res;
        } 
    }
    
err:
    freeHashTab(htab, N);
    return -1;    
}
View Code

代码稍微长一点就肯定有bug. 这次我遇到两个问题:

1. 在给数组扩容时, 我一开始的代码是这样:

    hp->np = (Node*)realloc(hp->np, capacity * sizeof(Node));
    if (hp->np == NULL)
        return -1;

这里的问题在于, 若realloc返回NULL, 则原来的内存 不会被清除. 所以这里有一个内存泄露.

2. 需要一个hash函数 把 n映射为 [0, N - 1]. 为简单计, 我的hash函数简单的定义为:

#define N 509
#define HASH_VAL(n) (n) % N

这是不对的. 考虑 n == -1, 则hash值为-1.

再来:

#define HASH_VAL(n) abs(n) % N

貌似可以了吧. 但还是不行, 呵呵, LC上的测试用例设计的非常好. 考虑 n为-2147483648, 则abs(n) = -2147483648.

注: 2147483648超出32位int型范围, 故 abs(-2147483648) 为undefined behavior.

最后改为:

#define HASH_VAL(n) abs((n) % N)

 

转载于:https://www.cnblogs.com/brayden/p/5233309.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是用 C 语言实现的哈希表: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE 10 struct Node { char* key; int value; struct Node* next; }; struct Node* hash_table[SIZE]; int hash(char* key) { int hash_value = 0; int length = strlen(key); for (int i = 0; i < length; i++) { hash_value = hash_value + key[i]; } return hash_value % SIZE; } void insert(char* key, int value) { int index = hash(key); struct Node* new_node = (struct Node*)malloc(sizeof(struct Node)); new_node->key = key; new_node->value = value; new_node->next = NULL; if (hash_table[index] == NULL) { hash_table[index] = new_node; return; } struct Node* current_node = hash_table[index]; while (current_node->next != NULL) { current_node = current_node->next; } current_node->next = new_node; } int get(char* key) { int index = hash(key); struct Node* current_node = hash_table[index]; while (current_node != NULL) { if (strcmp(current_node->key, key) == 0) { return current_node->value; } current_node = current_node->next; } return -1; } int main() { insert("apple", 2); insert("banana", 4); insert("cherry", 6); printf("Value of apple: %d\n", get("apple")); printf("Value of banana: %d\n", get("banana")); printf("Value of cherry: %d\n", get("cherry")); return 0; } ``` 这个哈希表实现包括一个 `Node` 结构体来表示哈希表中的每个节点,它包含一个键值对和一个指向下一个节点的指针成员。`hash` 函数用于计算键的哈希值,`insert` 函数用于插入键值对,`get` 函数用于获取键对应的值。在 `main` 函数中,我们插入了几个键值对,然后使用 `get` 函数获取这些键对应的值,并打印出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值