Day6——有效的字母异位词、两个数组的交集、快乐数、两数之和(哈希)

简介: Day6——有效的字母异位词、两个数组的交集、快乐数、两数之和(哈希)

前言


今日文案:

盐于律己,甜以待人

一、有效的字母异位词


题目描述:

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

题目来源:

力扣

解题思路:


本题主要是用的哈希结构是——数组。因为我们可以看到,我们的对象只是26个字母,长度比较小,所以我们可以创作数组结构来实现,如果很大的话我们会浪费很多空间。

数组的哈希结构,主要是我们创建一个哈希数组(就是普通数组,我们叫哈希数组是为了区分而已),然后去把目标数组遍历,把目标数组的值 通过处理,然后变成数组的下标,对应下标的哈希数组++,这样我们就可以通过比对找出我们想要的结果。

代码如下:

bool isAnagram(char * s, char * t){
    int arr[26]={0},a=1;
    for(int i=0;i<strlen(s);i++)            //遍历数组
    {    
        arr[s[i]-'a']++;                    //利用阿斯卡码值,得出对应下标++
    }
    for(int i=0;i<strlen(t);i++)
    {
        arr[t[i]-'a']--;          //这里注意是减减(外边有说明)
    }                          
    for(int i=0;i<26;i++)                    //如果你最后的数组都是0,说明字母出现次数是一样的                
    {
        if(arr[i]!=0)
        a=0;
    }
    if(a==0)
    return false;
    else
    return true;
}

关于那个- -的地方,也是我踩的一个坑,我最初的想法是,我都是++,然后数组里面出现的不是2就是0,不久可以认为两个字符串是一对一对出现的吗,这样不久等于消消乐一样,简简单单吗。

但是消消乐会消,我这里没有写啊,鬼知道一个字符串里面相同的字母会出现多少次次呢,因此我们通过- -来判断,==0就说明他们两个相互抵消辣~

二、两个数组的交集


问题来源:

力扣

1.数组解法(c)


上面我们学习了数组解法,我这题也尝试着使用了一下。因为要求两个数组的交集,那我们只要使用哈希数组,把数组出现的元素都保存好,然后用两个哈希数组一比对就知道是不是同时出现了。

代码如下:

int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int *p=(int *) malloc(sizeof(int)*1000);    //申请空间作为存放答案的地方
    int arr[1001]={0},brr[1001]={0},j=0;        //定义两个数组,作为哈希数组
    for(int i=0;i<nums1Size;i++)
    {
        arr[nums1[i]]++;                        //做第一个数组的哈希表
    }
    for(int i=0;i<nums2Size;i++)
    {    
        brr[nums2[i]]++;                        //第二个数组的哈希表
    }
    for(int i=0;i<1000;i++)
    {
        if(arr[i]>0&&brr[i]>0)            //比对两个哈希数组,同时大于0,是明是交集
        {
            p[j]=i;                    //保存好
            j++;
        }
    }
    *returnSize=j;                    //返回
    return p;
}

上面那种方法比较简单易懂,但是low,肯定有小伙伴不满足于此,下面我来解释另外一种哈希结构——set.

2、set解法(c++)


按我的理解(初学):unordered_set<int> 这种结构,它是可以自动帮你筛除去重复的元素,也就是说,储存的元素都是不重复的,而且空间是比较有弹性的,不需要像数组一样一次定义,可能会造成浪费。

代码如下:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> ans;
        int has[1000]={0},a=0;
        for(int i=0;i<nums1.size();i++)            //把目标数组1的值作为下标对应哈希数组置1
        {
            has[nums1[i]]=1;
        }
        for(int i=0;i<nums2.size();i++)    //用目标数组2的值作为下标索引
        {
            if(has[nums2[i]]==1)            //如果也等于1,那么说明是相交的
            {
                ans.insert(nums2[i]); //这里是插入相交的值,因为set,是不会插入重复的值的
                a++;
            }
        }
        return vector<int>(ans.begin(), ans.end());  //返回
    }
};

三、快乐数


题目来源:

力扣

思路:

1、首先我们可以看见,这个快乐数好像和我们的水仙花数有点类似,都是用每一位的和的平分加起来。但不一样的是,水仙花数只需要一次就可以判断了,但这个好像需要很多次,而且有可能进入死循环。

2、我们怎么判断死循环呢,当一个结果在里面重复出现了,我们就可以判断是死循环了,是一辈子得不到那个1的。

代码如下(示例):

int f(int n)                //计算函数
{
    int sum=0;
    while(n)
    {
        sum=(n%10)*(n%10)+sum;        //拆数
        n=n/10;
    }
    return sum;
}
class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> p;        //一个set结构
        while(1)
        {
            int sum=f(n);            //每次计算一次
            if(sum==1)
            return true;
            if(p.find(sum)!=p.end())        //因为find如果找不到那个值,它会=p.end()
            return false;
            else{
            p.insert(sum);            //如果没有找到1,也还没有判断进入死循环,把当前的sum插
            }                            入set里面,以后可以判断是否出现死循环
            n=sum;        //新的一轮起始数
        }
    }
};

四、两数之和


力扣第一题,真就,有人夜里开车看海,有人谈情说爱,有人力扣第一道题都写不出来呗。

题目来源:

力扣

思路:

1、暴力破解,没什么技术难度,两个for搞定。

2、用map。

代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> map;
        for(int i=0;i<nums.size();i++)
        {
            int w=target-nums[i];
            auto adr=map.find(w);
            if(adr!=map.end())
            return {adr->second,i};
            else
            map.insert(pair<int,int>(nums[i],i));
        }
        return {};
    }
};

关于map,我也没有了解得很明白,下面是我一点粗浅的理解:

map里面有两个数据类型,一个存地址一个存值,我们在这里只需要两步

1、搜索以前有没有出现这个值

2、存储出现的值

下面是四个需要思考的问题:


1、为什么想到用哈希法。

2、我们为什么要用map。

3、map究竟是用来干什么的。

4、map里面的key是用来存什么的。

ps :图书馆要关门了,交给你们了hhh

总结


今天是算法训练的第六天,新学了很多c++的东西,我也准备使用c++刷题了,加油加油!!!

相关文章
|
2天前
|
数据采集 人工智能 安全
|
11天前
|
云安全 监控 安全
|
3天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1014 151
|
3天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
16天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1709 9
|
8天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
652 152
|
10天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
618 12
|
10天前
|
人工智能 自然语言处理 API
Next AI Draw.io:当AI遇见Draw.io图表绘制
Next AI Draw.io 是一款融合AI与图表绘制的开源工具,基于Next.js实现,支持自然语言生成架构图、流程图等专业图表。集成多款主流大模型,提供智能绘图、图像识别优化、版本管理等功能,部署简单,安全可控,助力技术文档与系统设计高效创作。
689 151