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

news2025/2/24 12:33:20

打卡第六天,补昨天的卡

今日任务

  • 哈希表理论基础
  • 242.有效的字母异位词
  • 349.两个数组的交集
  • 202.快乐数
  • 1.两数之和

哈希表理论基础

哈希表是根据关键码的值而直接进行访问的数据结构。

哈希表能解决什么问题呢?

一般哈希表都是用来快速判断一个元素是否出现集合里

常见的三种哈希表:

  • 数组
  • set(集合):
  • map(映射):

242.有效的字母异位词

在这里插入图片描述

我的解题

class Solution {
public:
    bool isAnagram(string s, string t) {
        if(s.size() != t.size()) return false;
        int hash[26] = {0};
        for(int i = 0; i < s.size(); i++) {
            hash[s[i] - 'a'] ++;
        }
        for(int i = 0; i < t.size(); i++) {
            hash[t[i] - 'a'] --;
        }
        for(int i = 0; i < 26; i++) {
            if(hash[i] != 0) return false;
        }
        return true;
    }
};

把s的每一个字符丢进哈希表,然后遍历 t ,判断每个字符是否都出现在哈希表中,并且数量相同,多一个少一个都是false。

349.两个数组的交集

在这里插入图片描述

我的解题

暴力做法

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        sort(nums2.begin(), nums2.end());
        for(int i = 0; i < nums2.size(); i++) {
            for(int j = 0; j < nums1.size(); j++) {
                if(nums1[j] == nums2[i]) {
                    if(i > 0 && nums2[i - 1] == nums2[i]) break;
                    res.push_back(nums1[j]);
                    break;    
                }
            }
        }
        return res;
    }
};

将 nums2 排序,为什么要排序,因为题目要求结果每一个元素要唯一,排完序,当我们判断,后一个元素等于前一个元素,就可以直接跳过这个元素,这样不会造成结果元素不唯一。

返回第一层循环遍历 nums2,选定一个 nums2 元素,第二层循环遍历 nums1,查找nums1中是否有与 选定的 nums2 元素 相等的元素,有就存入结果集,并且跳出第二层循环,如果不 break,结果会重复。

哈希法

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        sort(nums2.begin(), nums2.end());
        unordered_set<int> mySet(nums1.begin(), nums1.end());
        vector<int> res;
        // for(int i = 0; i < nums1.size(); i++) {
        //     mySet.insert(nums1[i]);
        // }
        for(int i = 0; i < nums2.size(); i++) {
            if(mySet.find(nums2[i]) != mySet.end()) {
            	if(i > 0 && nums2[i] == nums2[i - 1]) continue;
            	res.push_back(nums2[i]);
            }	
        }
        return res;
    }
};

把 nums1 全部丢进去 unordered_set,循环遍历nums2,当在哈希表找到了于 nums2 相同的元素,存入结果集。

代码随想录

set做法

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
        unordered_set<int> nums_set(nums1.begin(), nums1.end());
        for (int num : nums2) {
            // 发现nums2的元素 在nums_set里又出现过
            if (nums_set.find(num) != nums_set.end()) {
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

拓展:

直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。

不要小瞧 这个耗时,在数据量大的情况,差距是很明显的。

数组做法

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        int hash[1010] = {0};
        unordered_set<int> res;
        for(int i = 0; i < nums1.size(); i++) hash[nums1[i]] = 1;
        for(int i = 0; i < nums2.size(); i++) {
            if(hash[nums2[i]]) 
                res.insert(nums2[i]);
        }
        return vector<int>(res.begin(), res.end());
    }
};

202.快乐数

在这里插入图片描述

我的解题

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

计算 该数每个位置上的数字的平方和。

int work(int n) {
   int res = 0;
   while(n) {
       res += (n % 10) * (n % 10);
       n /= 10;
   }
   return res;
} 

每一次计算都要判断是不是等于1,等于1就是快乐数,那什么时候不是快乐数,如果每一次计算每个位置上的数字的平方和 与前面某一次计算结果一样,就永远不可能等于 1。

例如示例2:
2 = 0 + 2 2 = 4 2 = 0 + 2^2 = 4 2=0+22=4
4 = 0 + 4 4 = 16 4 = 0 + 4^4 = 16 4=0+44=16
16 = 1 2 + 6 2 = 37 16 = 1^2 + 6^2 = 37 16=12+62=37
37 = 3 2 + 7 2 = 58 37 = 3^2 + 7^2 = 58 37=32+72=58
58 = 5 2 + 8 2 = 89 58 = 5^2 + 8^2 = 89 58=52+82=89
89 = 8 2 + 9 2 = 145 89 = 8^2 + 9^2 = 145 89=82+92=145
145 = 1 2 + 4 2 + 5 2 = 42 145 = 1^2 + 4^2 + 5^2 = 42 145=12+42+52=42
42 = 4 2 + 2 2 = 20 42 = 4^2 + 2^2 = 20 42=42+22=20
20 = 2 2 + 0 = 4 20 = 2^2 + 0 = 4 20=22+0=4

接下来继续计算,结果会一直循环,永远不会等于1。
所以用一个哈希表存储之前计算的结果,每次都判断是否跟之前结果重复,重复就返回 false。

代码随想录

!!!当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。

class Solution {
public:
    // 取数值各个位上的单数之和
    int getSum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> set;
        while(1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }
            // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
            if (set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

1.两数之和

在这里插入图片描述

我的解题

暴力做法

两层循环,先找一个数,再往后找一个数,相加判断是否等于target,不等于继续找,直到找到。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res(2);
        for(int i = 0; i < nums.size(); i++) {
            for(int j = i + 1; j < nums.size(); j++) {
                if(target == nums[i] + nums[j]) {
                    res[0] = i;
                    res[1] = j;
                    return res;
                }
            }
        }
        return res;
    }
};

不成功的哈希法

我一开始的想法是开一个 unorder_map ,把nums的数跟下标存进去,然后遍历寻找哈希表里是否有 target - nums[i],有的话就是找到结果。

但是后面发现我这样做,会重复选择两个元素相加,比如示例2,结果会是[0, 0]。

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

代码随想录

本题其实有四个重点:

  • 为什么会想到用哈希表?
    需要快速寻找一个数(target - nums[i]),所以考虑用哈希法

  • 哈希表为什么用map?
    题目需要返回的是下标,我们找的是值,需要存储两个数据,而map 是以键值对(pair类型)的形式存储数据,比较合适。

  • 本题map是用来存什么的?
    map目的用来存放我们访问过的元素,因为遍历数组的时候,需要记录我们之前遍历过哪些元素和对应的下标,这样才能找到与当前元素相匹配的(也就是相加等于target)

    因为map是存放访问过的元素,所以不会出现同一个元素在答案里重复出现的情况。因为当我们选择当前这个元素的时候,map里面只有在此之前访问过的元素,没有当前这个元素,所以像示例2,结果不会出现[0, 0]这个情况。

  • map中的key和value用来存什么的?
    map 的 key存放数组的元素,value存放数组元素的下标。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/362097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaDoc生成API文档(powernode document)(内含源代码和导出的文档)

JavaDoc生成API文档&#xff08;powernode document&#xff09;&#xff08;内含源代码和导出的文档&#xff09; 源代码和导出的文档下载链接地址&#xff1a;https://download.csdn.net/download/weixin_46411355/87473296 目录JavaDoc生成API文档&#xff08;powernode do…

恺望数据:解决智驾数据生产痛点,提供自动化生产线和规模化人力

最近Chat GPT引起了一个热点话题&#xff0c;就是人工智能是否真的可以替代人类工作&#xff0c;特别是在需要进行数据标注等需要人力的领域。 自动驾驶数据服务公司恺望数据在最近的一个会议上透露了一些消息&#xff0c;他们已经推出了一个基于自动化的数据生产系统&#xff…

linux下安装minio

获取 MinIO 下载 URL:访问&#xff1a;https://docs.min.io/ 一&#xff0c;进入/opt 目录&#xff0c;创建minio文件夹 cd /optmkdir minio二&#xff0c;wget下载安装包 wget https://dl.minio.io/server/minio/release/linux-amd64/minio三&#xff0c;进入minio文件夹创建…

蓝海创意云vLive虚拟直播亮相2023昆山元宇宙产品展览会

2月15日-19日&#xff0c;由中国计算机行业协会“元宇宙创见未来”2023元宇宙产品展览会在江苏昆山隆重召开&#xff0c;共吸引了省内外32家企业参展&#xff0c;展出近百款元宇宙产品或技术&#xff0c;涵盖芯片、显示、VR、AR等硬件设备&#xff0c;以及工业、文旅、娱乐、教…

golang及goland的安装

1.电脑环境 2.软件下载 链接&#xff1a;https://pan.baidu.com/s/1YHM_jazftwkqRAuxJqMHZg 提取码&#xff1a;cdbm go1.17.5.windows-amd64.msi是go语言的开发及运行环境类似于Java的JDK。 goland-2020.2.2.exe 是go语言的开发工具(IDE),类似于Java的 Intelli J IDEA。 3…

【计算机网络】应用题方法总结

0.前言本篇博客主要记录自己在学习到的部分解决计算机网络应用题方法&#xff0c;主要参考视频如下&#xff1a;计算机网络期末复习 应用题_哔哩哔哩_bilibili【计算机网络】子网划分题型总结_哔哩哔哩_bilibili循环冗余码step 1&#xff1a;确定冗余码长度。多项式最高位即为冗…

阶段二11_面向对象高级_学生管理系统案例1

说明&#xff1a;学生管理系统案例需求和步骤1请查看上一张《阶段二10_面向对象高级_分类分包思想》 一.学生管理系统案例 步骤2&#xff1a;搭建主菜单和学生管理系统菜单 (0).主菜单和学习菜单界面和思路 界面&#xff1a; --------欢迎来到信息管理系统-------- 请输入您的…

CMake编译opencv4.6

openCV系列文章目录 文章目录openCV系列文章目录前言一、准备工作二、使用步骤1.使用CMake编译openCV总结前言 最近在项目中遇到图片处理&#xff0c;一拍脑袋就想到大名鼎鼎的opencv 一、准备工作 1.openCV官网下载 2.CMake官方下载 3.vs2019官方下载 二、使用步骤 1.使用…

[ vulhub漏洞复现篇 ] Drupal XSS漏洞 (CVE-2019-6341)

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

Qt基础之二十九:图形视图框架(Graphics View Framework)及其应用

无意中从网络获取一份俄罗斯方块源码,基于图形视图框架(Graphics View Framework)实现的。当然源码的核心从来都不是界面,而是方块的移动、变形和消除等算法。源码非常完整,注释详细,经改动后已能在Qt5中运行,下面是运行效果,背景音乐和音效也是有的。 一.效果 二.原理 …

Spring MVC 源码 - HandlerMapping 组件(二)之 HandlerInterceptor 拦截器

HandlerMapping 组件HandlerMapping 组件&#xff0c;请求的处理器匹配器&#xff0c;负责为请求找到合适的 HandlerExecutionChain 处理器执行链&#xff0c;包含处理器&#xff08;handler&#xff09;和拦截器们&#xff08;interceptors&#xff09;handler 处理器是 Objec…

复旦大学邱锡鹏团队发布类 ChatGPT 模型MOSS

不知道这个人工智能&#xff0c;有没有获得完整的一生。 ChatGPT 是最先进的 AI&#xff0c;也是最热门的应用 —— 自去年 11 月底发布以来&#xff0c;它的月活跃用户两个月超过一亿&#xff0c;轻松拿到了全球互联网史上用户增长速度的第一。 它也是一种门槛很高的技术。由…

Metasploit 使用篇(二)

文章目录前言一、侦察1.banner信息2.http头检测小结二、枚举DNS枚举枚举文件三、漏洞扫描四、漏洞评估前言 内容均来自《Web渗透测试实战 基于Metasploit5.0》&#xff0c;包括渗透测试生命周期中的4个部分&#xff1a; 侦察Web应用枚举漏洞扫描漏洞评估 以对metasplitable …

入门力扣自学笔记236 C++ (题目编号:1326)(贪心算法)

1326. 灌溉花园的最少水龙头数目 题目&#xff1a; 在 x 轴上有一个一维的花园。花园长度为 n&#xff0c;从点 0 开始&#xff0c;到点 n 结束。 花园里总共有 n 1 个水龙头&#xff0c;分别位于 [0, 1, ..., n] 。 给你一个整数 n 和一个长度为 n 1 的整数数组 ranges …

江南爱窗帘十大品牌 | 推荐3种简单的窗帘上色方法

窗帘可以在色彩搭配好的空间里营造温度和情调&#xff1f;窗帘不仅是用来挡光的&#xff0c;更能营造温暖和氛围家。除了成品家具&#xff0c;家中软装的另一大部分就是窗帘了。窗帘的颜色搭配好&#xff0c;我们家瞬间有温度。今天我们将讨论一些简单的窗帘上色方法。1、窗帘我…

计算机网络基础知识--数据链路层协议

目录 使用点对点信道的数据链路层 数据链路层的三个基本问题 封装成帧 透明传输 差错检测 点对点协议PPP PPP协议的组成 PPP帧的格式 数据链路层的协议数据单元是帧。数据链路层把网络层交下来的数据构成帧发送到链路上&#xff0c;以及把接收到的帧中的数据取出并上交网…

VR全景带你打卡《狂飙》经典取景地!

热度“狂飙”&#xff01;电视剧《狂飙》的取景地——江门墟顶老街人气火爆&#xff0c;720VR全景带您了解&#xff0c;这个具有新活力的老街区&#xff0c;蛙色3DVR提供技术支持&#xff01;通过航拍VR全景&#xff0c;全方位展示江门历史文化街区&#xff0c;720浏览&#xf…

3 nacos与其他注册中心对比以及提升

对比如下&#xff1a; CAP模型&#xff1a; 计算机专家 埃里克布鲁尔&#xff08;Eric Brewer&#xff09;于 2000 年在 ACM 分布式计算机原理专题讨论会&#xff08;简称&#xff1a;PODC&#xff09;中提出的分布式系统设计要考虑的三个核心要素&#xff1a; (1) 一致性&am…

appium自动化测试

获取应用包名和入口activity&#xff1a;aapt命令 aapt目录&#xff1a; 安卓sdk的build-tools目录下(如果要在cmd里直接运行&#xff0c;要配置环境变量&#xff0c;否则需要在aapt所在目录下打开cmd) 示例&#xff1a; adt-bundle-windows-x86_64-20140702\sdk\build-too…

微信小程序开发(二)

一、封装request.js请求文件 目的&#xff1a;优化代码结构以及后期项目版本迭代和维护更加方便&#xff0c;提升代码的执行速度。 假设在原生page中使用基本写法创建ajax请求&#xff0c;则会出现以下问题&#xff1a; 1、page界面业务操作代码混乱&#xff0c;代码多层嵌套…