算法训练营打卡Day6

文章目录

概要

#打卡内容主题:哈希表(hash_table)#

1、什么时候使用哈希表?

使用场景

基于std::unordered_set和std::unordered_map的底层实现都为哈希表,它们都无序其查询效率、增删效率都是O(1),当我们遇到了要快速判断一个元素是否出现集合里的时候,首先考虑哈希法。但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。哈希表的key值不可修改。

题目1.242.有效的字母异位词

题目链接:. - 力扣(LeetCode)学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词_哔哩哔哩_bilibili. - 力扣(LeetCode)

思路分享(先前已做过):

①先分享python代码思路:

#把数组中的元素都先转换成ASCII码,接着排序-->然后比较两个数组的和-->返回True/False

#这是很好理解比较简单的思路。

class Solution(object):

    def isAnagram(self, s, t):

        """

        :type s: str

        :type t: str

        :rtype: bool

        """

        #把字符串中的每个字符转换成ASCII码,然后排序

        lst1 = []

        lst2 = []

        for i in s:

            i = ord(i)

            lst1.append(i)

        for j in t:

            j = ord(j)

            lst2.append(j)

        if sorted(lst1) == sorted(lst2):

            return True

        else:

            return False

        #然后判断排序后的结果是否相同

再分享C代码思路:

#include <string.h>

bool isAnagram(char* s, char* t) {

    //char* s和char* t是字符串指针

    //可以先考虑特殊情况,假如两个字符串的长度不同,直接返回false

    if (strlen(s) != strlen(t)) {  

        return false;  

    }

    // 使用数组记录字符出现次数  

    int sCount[26] = {0};  

    int tCount[26] = {0};  

    // 统计s中每个字符的出现次数  

    for (int i = 0; s[i] != '\0'; i++) {  

        if (s[i] >= 'a' && s[i] <= 'z') {

            //数组中对于数字出现次数加1  

            sCount[s[i] - 'a']++;  

        }  

    }

    // 统计s中每个字符的出现次数  

    for (int i = 0; t[i] != '\0'; i++) {  

        if (t[i] >= 'a' && t[i] <= 'z') {  

            sCount[s[i] - 'a']++;  

        }  

    }

    //比较两个数组

    //比较两个数组是否完全相同  

    for (int i = 0; i < 26; i++) {  

        if (sCount[i] != tCount[i]) {  

            return false;  

        }  

    }  

    // 如果所有字符的出现次数都相同,则它们是字母异位词  

    return true;  

}

附官方题解(实在是很简短啊!!):

int cmp(const void* _a, const void* _b) {
    char a = *(char*)_a, b = *(char*)_b;
    return a - b;
}

bool isAnagram(char* s, char* t) {
    int len_s = strlen(s), len_t = strlen(t);
    if (len_s != len_t) {
        return false;
    }
    qsort(s, len_s, sizeof(char), cmp);
    qsort(t, len_t, sizeof(char), cmp);
    return strcmp(s, t) == 0;
}
链接:https://leetcode.cn/problems/valid-anagram/solutions/493231/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode-solution/

题目2.349.两个数组的交集

题目链接:. - 力扣(LeetCode)学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibili

题目难度不大,可以参考笔者或者上面链接的思路(连彩笔笔者都几分钟搞定了)

①python版本思路:

class Solution(object):  

    def intersection(self, nums1, nums2):  

        # 将 nums1 转换为集合以提高查找效率  

        set1 = set(nums1)  

        # 初始化结果列表  

        res = []  

        # 遍历 nums2,检查每个元素是否在 set1 中  

        for num in nums2:  

            if num in set1:  

                res.append(num)  

                # 可选:如果结果中不需要重复元素,则可以从集合中移除已找到的元素  

                # set1.remove(num)  

        # 返回结果列表  

        return list(set(res))  

②C语言思路(笔者刚接触哈希表,对C语言写法一头雾水,参考官解):

struct unordered_set {
    int key;
    UT_hash_handle hh;
};

struct unordered_set* find(struct unordered_set** hashtable, int ikey) {
    struct unordered_set* tmp;
    HASH_FIND_INT(*hashtable, &ikey, tmp);
    return tmp;
}

void insert(struct unordered_set** hashtable, int ikey) {
    struct unordered_set* tmp = find(hashtable, ikey);
    if (tmp != NULL) return;
    tmp = malloc(sizeof(struct unordered_set));
    tmp->key = ikey;
    HASH_ADD_INT(*hashtable, key, tmp);
}

int* getIntersection(struct unordered_set** set1, struct unordered_set** set2, int* returnSize) {
    if (HASH_COUNT(*set1) > HASH_COUNT(*set2)) {
        return getIntersection(set2, set1, returnSize);
    }
    int* intersection = malloc(sizeof(int) * (HASH_COUNT(*set1) + HASH_COUNT(*set2)));
    struct unordered_set *s, *tmp;
    HASH_ITER(hh, *set1, s, tmp) {
        if (find(set2, s->key)) {
            intersection[(*returnSize)++] = s->key;
        }
    }
    return intersection;
}

int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
    *returnSize = 0;
    struct unordered_set *set1 = NULL, *set2 = NULL;
    for (int i = 0; i < nums1Size; i++) {
        insert(&set1, nums1[i]);
    }
    for (int i = 0; i < nums2Size; i++) {
        insert(&set2, nums2[i]);
    }

    return getIntersection(&set1, &set2, returnSize);
}
链接:https://leetcode.cn/problems/intersection-of-two-arrays/solutions/469445/liang-ge-shu-zu-de-jiao-ji-by-leetcode-solution/

int cmp(void* a, void* b) {
    return *(int*)a - *(int*)b;
}

int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
    qsort(nums1, nums1Size, sizeof(int), cmp);
    qsort(nums2, nums2Size, sizeof(int), cmp);
    *returnSize = 0;
    int index1 = 0, index2 = 0;
    int* intersection = malloc(sizeof(int) * (nums1Size + nums2Size));
    while (index1 < nums1Size && index2 < nums2Size) {
        int num1 = nums1[index1], num2 = nums2[index2];
        if (num1 == num2) {
            // 保证加入元素的唯一性
            if (!(*returnSize) || num1 != intersection[(*returnSize) - 1]) {
                intersection[(*returnSize)++] = num1;
            }
            index1++;
            index2++;
        } else if (num1 < num2) {
            index1++;
        } else {
            index2++;
        }
    }
    return intersection;
}
链接:https://leetcode.cn/problems/intersection-of-two-arrays/solutions/469445/liang-ge-shu-zu-de-jiao-ji-by-leetcode-solution/

题目3.快乐数

C-Code:

bool isHappy(int n) {

    int sum = 0;

    int count = 0;

    while (sum!=1 && count<50){

        while(n!=0){

            sum = sum + (n%10)*(n%10);

            n = n/10;

        }

        if (sum==1){

            return true;

        }

        n = sum;

        sum = 0;

        count++;

    }

    return false;

}

小结

今日疑问:

1、qsort()函数用法

2、struct unordered_set 、struct unordered_set* find(struct unordered_set** hashtable, int ikey) 中初始化的值有什么含义

3、什么时候运用以及如何运用哈希表

4、完成leetcode第1题.两数之和(使用哈希表)

路漫漫其修远兮,吾将上下而求算法之道~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值