【leetcode】136. 只出现一次的数字

题目:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

题目链接https://leetcode-cn.com/problems/single-number/

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4

对于该题目的分析,最好的做法是用异或运算求解,但是我们的目的不是为了pass这道题,而是在C语言的base上使用uthash来解算这道题,从而提高对uthash的掌握程度。

Leetcode-cn官方的环境说明采用的C编译器已经升级为gcc 8.2,默认包含了"uthash.h"。我们用C语言对uthash提供的宏以int作为key进行简单的封装如下,使用时直接拷贝到leetcode答题面板上即可:

//#include <securec.h> // 安全函数库
#include "uthash.h"

struct my_struct {
    int id; /* key */
    char name[10];
    UT_hash_handle hh; /* makes this structure hashable */
};

struct my_struct *g_hash = NULL;

void hash_add_ikey(int ikey_id, char *name)
{
    struct my_struct *s;

    HASH_FIND_INT(g_hash, &ikey_id, s); /* id already in the hash? */
    if (s == NULL) {
        s = (struct my_struct *)malloc(sizeof *s);
        s->id = ikey_id;
        HASH_ADD_INT(g_hash, id, s); /* id: name of key field */
    }
    // strcpy_s(s->name, 10 * sizeof(char), name); // 自行判断是否使用安全函数,这里不要sizeof(s->name)
    strcpy(s->name, name);
}

struct my_struct *hash_find_ikey(int ikey_id)
{
    struct my_struct *s;

    HASH_FIND_INT(g_hash, &ikey_id, s); /* s: output pointer */
    return s;
}

void hash_delete_ikey(struct my_struct *ikey)
{
    struct my_struct *s = NULL;

    HASH_FIND_INT(g_hash, &ikey, s);
    if (s == NULL) {
        HASH_DEL(g_hash, ikey); /* ikey: pointer to delete */
        free(ikey);
    }
}

void hash_delete_all()
{
    struct my_struct *current_ikey, *tmp;

    HASH_ITER(hh, g_hash, current_ikey, tmp)
    {
        HASH_DEL(g_hash, current_ikey); /* delete it (g_hash advances to next) */
        free(current_ikey);             /* free it */
    }
}

void hash_print()
{
    struct my_struct *s;

    for (s = g_hash; s != NULL; s = (struct my_struct *)(s->hh.next)) {
        printf("ikey id %d: name %s\n", s->id, s->name);
    }
}

int name_sort(struct my_struct *a, struct my_struct *b)
{
    return strcmp(a->name, b->name);
}

int id_sort(struct my_struct *a, struct my_struct *b)
{
    return (a->id - b->id);
}

void hash_sort_by_name()
{
    HASH_SORT(g_hash, name_sort);
}

void hash_sort_by_id()
{
    HASH_SORT(g_hash, id_sort);
}

unsigned int hash_get_count()
{
    return HASH_COUNT(g_hash);
}

这道题目使用uthash的解法:

编译nums的每一个元素,如果hash_table里存在当前元素,则删除,如果不存在,则添加,最终将剩余1个不重复的元素。

int singleNumber(int* nums, int numsSize){
    int res;
    for(int i = 0; i < numsSize; i++) {
        struct my_struct *s = hash_find_ikey(nums[i]);
        if (s == NULL) {
            hash_add_ikey(nums[i], "1");
            printf("add_ikey, %d\n", nums[i]);
        } else {
            hash_delete_ikey(s);
            printf("delete_ikey, %d\n", nums[i]);
        }
    }

    res = g_hash->id;
    printf("count %d\n", hash_get_count());
    hash_print();
    hash_delete_all(); // 由于g_hash为全局变量,运行结束后要清空
    return res;
}

用例执行结果:

输入
[4,1,2,1,2]

输出
4

预期结果
4

stdout
add_ikey, 4
add_ikey, 1
add_ikey, 2
delete_ikey, 1
delete_ikey, 2
count 1
ikey id 4: name 1

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值