代码随想录算法训练营第六天 | 哈希表part01 | 242.有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和

掌握一点C++

C语言不太做的了哈希。C语言要求在数组定义时就指定固定的数组长度,且没有C++中各种丰富的容器。了解一点C++基本语法和容器

for(int a: b)

for(int a:b) 从数组b依次取出元素赋值给整形变量a,循环执行for中语句

c++ 中文参考手册

vector

动态数组,顺序容器

https://www.cnblogs.com/Nonono-nw/p/3462183.html

unordered_set

值唯一,无序

https://blog.csdn.net/LiuXF93/article/details/120899401

判断一个元素是否在容器中

 if((nums1_set.find(num)) != (nums1_set.end()))

 unordered_map

无序字典

auto

 auto关键字并不是一种实际的数据类型,它是一占位符,在编译阶段替换为真正的类型。


242.有效的字母异位词

题目来源:leetcode 题库242.有效的字母异位词

题目字符串只包含26个小写字母,创建长度为26的统计数组。

小写字母字符['a' , 'z'], 减去'a'后能得到[0,25]的范围。

字符串以'\0'为结束符。

遍历第一个字符数组,在统计数组中统计每个小写字母字符存在的数量,

遍历第二个字符数组,在统计数组中减去每个小写字母字符存在的数量,

遍历统计数组,若存在不为0的元素,说明两个字符数组不为字母异位词,

题解

bool isAnagram(char * s, char * t){
    int i = 0;
    int counters[26] = {0};
    bool Ret = true;
    while(*s != '\0')
    {
        counters[*s - 'a']++;
        s++;
    }
    while(*t != '\0')
    {
        counters[*t - 'a']--;
        t++;
    }
    for(i = 0; i < 26; i++)
    {
        if(counters[i] != 0)
        {
            Ret = false;
            break;
        }
    }
    return Ret;
}

  349. 两个数组的交集 

题目来源:leetcode 题库 349. 两个数组的交集

数组哈希

题目限制了两个数组的元素范围

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

数组中元素的范围为[0, 1000]因此可以使用数组做哈希来求解

创建一个长度为1001的数组,用于记录数组元素是否出现过

遍历第一个数组,记录数组中出现过的元素

遍历第二个数组,记录数组中出现过的元素

遍历记录数组,某数值在两个数组中都出现过,将其添加到返回数组

题解

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int counters[1001] = {0};
    int i, j = 0;
    int* Ret = (int*)malloc(sizeof(int)*1001);
    for(i = 0; i < nums1Size; i++)
    {
        counters[nums1[i]] = 0x01;
    }
    for(i = 0; i < nums2Size; i++)
    {
        counters[nums2[i]] |= 0x10;
    }
    for(i = 0; i < 1001; i++)
    {
        if(counters[i] == 0x11)
        {
            Ret[j++] = i;
        }
    }
    *returnSize = j;
    return Ret;
}

使用unordered_set

思路略

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set;
        unordered_set<int> nums1_set(nums1.begin(), nums1.end());
        for(int num : nums2)
        {
            if((nums1_set.find(num)) != (nums1_set.end()))
            {
                result_set.insert(num);
            }
        }
        return vector<int> (result_set.begin(), result_set.end());
    }
};

202. 快乐数

 题目来源:leetcode 题库 202. 快乐数

使用unordered_set容器记录计算各位平方和的数过程中出现过的平方和值,若在出现1之前,某个数重复出现,说明陷入了循环,不再可能计算出容器记录过的之外的值,该初值不是快乐数

题解

class Solution {
public:
    bool isHappy(int n) {
        bool Ret = true;
        unordered_set<int> mySet{n};
        int sum = 0;
        while(n != 1)
        {
            while(n != 0)
            {
                sum += (n % 10) * (n % 10);
                n = n /10;;
            }
            if(mySet.find(sum) != mySet.end())
            {
                Ret = false;
                break;
            }
            mySet.insert(sum);
            n = sum;
            sum = 0;
        }
        return Ret;
    }
};

1. 两数之和

题目来源:leetcode 题库 1. 两数之和 

 创建unordered_map,  存储结构为 {key:数组元素,value:数组元素对应的索引}

从头开始遍历,判断当前数组元素的要求组成目标值的另一个数是否再unordered_map中,

        若存在,找到值,退出循环返回

        若不存在,将当前数组元素及其索引加入ordered_map,继续遍历

题解

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map <int, int> myMap;
        vector<int> Ret;
        int i;
        for(i = 0; i < nums.size(); i++)
        {
            auto iter = myMap.find(target - nums[i]);
            if(iter != myMap.end())
            {
                return {iter->second, i};
            }
            myMap.insert(pair<int, int>(nums[i], i));
        }
        return {};
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值