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

news2024/9/22 16:52:03

哈希表

首先什么是 哈希表,哈希表(英文名字为Hash table,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道都是指hash table就可以了)。

那么哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里。

哈希函数

如下图所示,通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。

如果hashCode得到的数值大于 哈希表的大小了,也就是大于tableSize了,怎么办呢?

此时为了保证映射出来的索引数值都落在哈希表上,我们会在再次对数值做一个取模的操作,就要我们就保证了学生姓名一定可以映射到哈希表上了。

此时问题又来了,哈希表我们刚刚说过,就是一个数组。

如果学生的数量大于哈希表的大小怎么办,此时就算哈希函数计算的再均匀,也避免不了会有几位学生的名字同时映射到哈希表 同一个索引下标的位置。

接下来哈希碰撞登场

哈希碰撞

一般哈希碰撞有两种解决方法, 拉链法和线性探测法。

 拉链法

刚刚小李和小王在索引1的位置发生了冲突,发生冲突的元素都被存储在链表中。 这样我们就可以通过索引找到小李和小王了

(数据规模是dataSize, 哈希表的大小为tableSize)

其实拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。

线性探测法

使用线性探测法,一定要保证tableSize大于dataSize。 因为我们需要依靠哈希表中的空位来解决碰撞问题。例如冲突的位置,放了小李,那么就向下找一个空位放置小王的信息。所以要求tableSize一定要大于dataSize ,要不然哈希表上就没有空置的位置来存放 冲突的数据了。如图所示:

常见的三种哈希结构

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

242. 有效的字母异位词

思路:一开始利用hashmap一直做不出来,看了题解思路,自定义一个26位的数组arr,先将s的字符都在arr上标记(做加法),再将t的字符也在arr上标记(做减法),最后观察arr的变化

class Solution {
    public boolean isAnagram(String s, String t) {
        //将s放入hash表中,个数
        //判断t中每一个字符在s中是否存在
        int[] arr=new int[26];
        for(int i=0;i<s.length();i++){
            arr[s.charAt(i)-'a']++;//目的是使得相同字母能够定位到同一索引
        }
        for(int i=0;i<t.length();i++){
            arr[t.charAt(i)-'a']--;//目的是使得相同字母能够定位到同一索引
        }
        for(int i=0;i<arr.length;i++){
            if(arr[i]!=0){//如果是负数或者正数,则说明s和t肯定是不相同的
                return false;
            }
        }
        return true;
    }
}

349. 两个数组的交集

只会使用HashSet求解,看卡哥的解答是说用数组方式解答会更好,但是暂时没想到数组怎么做,

虽然代码AC了但是时间和空间复杂度都很低,垫底的存在,看了卡哥的思路跟我的思路是差不多的,但感觉哪里还能优化的呀。。

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        //使用set,或是使用数组
      //  唯一元素
      HashSet<Integer> set=new HashSet<Integer>();
      HashSet<Integer> res=new HashSet<Integer>();
      for(int i:nums1){
          set.add(i);
      }
      for(int i:nums2){
          if(set.contains(i)){
              res.add(i);
          }
      }
      return res.stream().mapToInt(Integer::intValue).toArray();



    }
}

 学到了利用io流把集合转换成数组

下面是相同的方法:只是我对lambda表达式不熟练所以多看看写写

     return res.stream().mapToInt(x -> x).toArray();
HashSet<Integer> set = new HashSet();
int[] a = set.stream().mapToInt(Integer::intValue).toArray()

202. 快乐数

这道题没有思路看的题解

数字n的最终结局分三种情况:

  1.最终会得到 1。
  2.最终会进入循环。
  3.值会越来越大,最后接近无穷大。这种情况不可能存在解释如下:

情况3不可能存在,因为三位数999的下一位是81+81+81=243,9999的下一位是324

对于 3 位数的数字,它不可能大于 243。这意味着它要么被困在 243 以下的循环内,要么跌到 1。4 位或 4 位以上的数字在每一步都会丢失一位,直到降到 3 位为止。所以我们知道,最坏的情况下,算法可能会在 243 以下的所有数字上循环,然后回到它已经到过的一个循环或者回到 1。但它不会无限期地进行下去,所以我们排除第三种选择。

思路1-哈希法

个人理解

这道题目使用哈希法,来判断这个sum是否重复出现

这道题首先要获取下一个数,其次要判断这个数是否存在我们的集合中,如果存在,那么说明陷入循环了可以返回false,否则就一直重复获取下一个数

class Solution {
    public boolean isHappy(int n) {
        /**
        1.最终会得到 1。
        2.最终会进入循环。
        3.值会越来越大,最后接近无穷大。这种情况不可能存在
         */
    
        HashSet<Integer> set=new HashSet<Integer>();
//因为最多有 log n个数字会加入到set中


        while(n!=1&&!set.contains(n)){//不包含这个数说明我们没有进入循环
           set.add(n);
           //不断更新n
            n=getNext(n);
        }

        return n==1;

    }
    public int getNext(int n){
        int res=0;
        while(n>0){
            int temp=n%10;
            res+=temp*temp;

            n/=10;

        }
        return res;

    }
}

思路2-双指针

通过反复调用 getNext(n) 得到的链是一个隐式的链表。如果n最终不会变成1,说明是这之间存在一个循环,如果存在循环的话,fast和slow指针二者最终是会相遇的

class Solution {
 
    //快慢指针,如果n不可能变成1,那一定是一个循环,快慢指针终会相遇
      public boolean isHappy(int n) {
        /**
        1.最终会得到 1。
        2.最终会进入循环。
        3.值会越来越大,最后接近无穷大。这种情况不可能存在
         */
         int fast=getNext(n);//fast先走一步,同时出发报错
         int slow=n;
         //通过反复调用 getNext(n) 得到的链是一个隐式的链表。
        // 两种结束循环的情况是:如果 n 是一个快乐数,即没有循环,那么快跑者最终会比慢跑者先到达数字 1。如果 n 不是一个快乐的数字,那么最终快跑者和慢跑者将在同一个数字上相遇。
        while(fast!=1&&fast!=slow){
           slow = getNext(slow);//走一步
           fast = getNext(getNext(fast));//走两步
        }
        return fast==1;
    }
    public int getNext(int n){
        int res=0;
        while(n>0){
            int temp=n%10;
            res+=temp*temp;
            n/=10;
        }
        return res;

    }

}

1.两数之和

半个月前做出来过,今天没做出来,尝试新思路也失败了,于是看了之前的提交记录

class Solution {
    public int[] twoSum(int[] nums, int target) {
        //两个for循环可以解决
        //使用hashmap?
       
先把所有数字放到map中,
然后再遍历数组nums[i],
再在map中寻找target-nums[i],
注意要先把map中nums[i]对应的value-1,这个思路复杂,做不出来

        //乖乖看题解
        HashMap<Integer,Integer> map=new HashMap<Integer,Integer>();
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(nums[i])){
                return new int[]{i,map.get(nums[i])};//注意,这里是map.get(nums[i]

            }
            map.put(target-nums[i],i);//补数,索引

            
        }
        return new int[]{-1,-1};

      
    }
}

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

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

相关文章

cypress 教程

cypress 教程 cypress是一个用于Web应用程序的端到端测试框架。它是一个开源的js测试工具&#xff0c;设计的目的是Web应用程序的测试能更快速、简单和可靠。赛普斯允许开发人员编写模拟用户交互和验证应用程序行为的自动测试。 我们可以使用js或者ts来开发&#xff0c;但是j…

用牛鲨水豚赚取SUI的机会又来喽,500万SUI奖励等你来领!

刚刚结束的第一轮Bullshark Quest真是一次惊心动魄的体验&#xff01;我们非常感激社区成员的积极参与以及对Sui生态系统的关注。此轮获奖者的奖励已于美国时间2023年7月28日&#xff0c;在Quest门户网站上公布。参与者点击“Claim”即可将奖励领取至Sui钱包。请注意&#xff0…

猿创征文|弃文从工,从小白到蚂蚁工程师,我的 Java 成长之路

一、前言 1.1 背景 最近 CSDN 开展了猿创征文&#xff0c;希望博主写文章讲述自己在某个领域的技术成长历程。 之前也曾想找个机会写篇文章&#xff0c;记录下自己的成长历程。 因此&#xff0c;借着这个机会写下这篇文章。 在回顾自己的成长历程的同时&#xff0c;希望对一…

红队打靶:FourAndSix2.01打靶思路详解(vulnhub)

目录 写在开头 第一步&#xff1a;主机发现与端口扫描 第二步&#xff1a;NFS渗透 第三步&#xff1a;7z压缩包的密码破解 第四步&#xff1a;ssh私钥登录 第五步&#xff1a;lessvi提权 总结与思考 写在开头 本篇博客根据大佬红队笔记的视频进行打靶&#xff0c;详述了…

基于Caffe的静默活体检测识别分析系统

周末的时候看到一个好玩的项目就想着实际拿来使用一下&#xff0c;这个项目主要是做的是开源的跟人脸活体检测相关的内容&#xff0c;这里主要采用的是静默活体检测的方式。 人脸静默活体检测是一种用于验证人脸是真实、活体的技术&#xff0c;而不需要进行任何口头指令或特定…

13.7 CentOS 7 环境下大量创建帐号的方法

13.7.1 一些帐号相关的检查工具 pwck pwck 这个指令在检查 /etc/passwd 这个帐号配置文件内的信息&#xff0c;与实际的主文件夹是否存在等信息&#xff0c; 还可以比对 /etc/passwd /etc/shadow 的信息是否一致&#xff0c;另外&#xff0c;如果 /etc/passwd 内的数据字段错…

Linux 给用户 赋某个文件夹操作的权限(实现三权分立)

Linux 给用户 赋某个文件夹操作的权限 这里用的ubuntu16.04 一、配置网站管理员 linux文件或目录的权限分为&#xff0c;读、写、可执行三种权限。文件访问的用户类别分为&#xff0c;文件创建者、与文件创建者同组的用户、其他用户三类。 添加用户 useradd -d /var/www/htm…

解密低价正规渠道的来源:影视会员肯德基点餐直充api接口

话费充值 接口已经整合移动、联通、电信三网话费充值渠道。话费可以说是全民所需&#xff0c;对于平台引流&#xff0c;增强平台日活跃度可以提供不小的帮助。 肯德基在线点餐 接口整合了各大城市的肯德基门店&#xff0c;支持门店选择&#xff0c;在线点餐 提前点餐领取&a…

linux系统编程重点复习--线程同步

目录 复习目标&#xff1a; 1 互斥锁 1.1互斥锁的使用步骤 1.2 练习 1.3 死锁 2 读写锁 3 条件变量 4 信号量 复习目标&#xff1a; 熟练掌握互斥量的使用说出什么叫死锁以及解决方案熟练掌握读写锁的使用熟练掌握条件变量的使用理解条件变量实现的生产消费者模型理解…

Java基础篇_1.2——保留关键字、基本数据类型、基本数据类型之间的转换

​​​​​​​目录 一、保留关键字 二、Java的基本数据类型 三、引用数据类型 四、基本数据类型间的转换 隐含强制类型转换 一、保留关键字 Java该语言是用 Unicode 字符集编写的。 Java关键字是预先定义的具有特别意义的标识符&#xff0c;也被称为Java保留字&#xff0…

在k8s集群内搭建Prometheus监控平台

基本架构 Prometheus由SoundCloud发布&#xff0c;是一套由go语言开发的开源的监控&报警&时间序列数据库的组合。 Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态&#xff0c;任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的…

YOLOv8教程系列:三、使用YOLOv8模型进行自定义数据集半自动标注

YOLOv8半自动标注 目标检测半自动标注的优点包括&#xff1a; 1.提高标注效率&#xff1a;算法能够自动标注部分数据&#xff0c;减少了人工标注的工作量&#xff0c;节省时间和资源。 2.降低成本&#xff1a;自动标注可以减少人工标注的成本&#xff0c;特别是对于大规模数据…

如何在线制作闪图?手把手教你快速生成GIF闪图

网上那种卟玲卟领的闪动GIF图片效果非常的炫丽&#xff0c;这种GIF闪图是怎么制作的呢&#xff1f;很简单&#xff0c;只需要使用专业的gif制作&#xff08;https://www.gif.cn/&#xff09;工具-GIF中文网&#xff0c;上传多张颜色、大小不同&#xff0c;内容相同的jpg、png格…

ORB-SLAM3数据集配置与评价

在ORB-SLAM3运行EuRoC和TUM-VI数据集并作以评价。EuRoC利用微型飞行器(MAV ) 收集的视觉惯性数据集&#xff0c;TUM-VI 是由实验人员手持视觉-惯性传感器收集的数据集。这两个是在视觉SLAM中比较常用的公开数据集&#xff0c;所以测试并加以记录。 文章目录 一、EuRoC数据集测…

音频转文字软件免费版让你快速完成转换

音频转文字技术是一种将音频文件转换为文本形式的技术&#xff0c;它可以帮助人们更方便地获取和处理音频信息。在实际生活和工作中&#xff0c;我们可能会遇到需要将音频转换为文字的情况&#xff0c;比如听取会议录音、收听讲座、学习外语等等。那么&#xff0c;你知道音频转…

Tinkercad 建模21个小技巧

21个Tinkercad 建模小技巧 原文 参考文章&#xff1a;在 Tinkercad 中加快设计的 22 个技巧 一起来了解一下21个Tinkercad 3D建模小技巧&#xff0c;让你快人一步。 技巧1 Copy & Paste 文件&#xff0c;整合设计 想把文件A里面的模型拷贝到文件B里面&#xff1f; 很容…

【Linux命令200例】mren一个用于重命名文件或目录的命令行工具

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜活的实操案例对各个命令进行深入…

msvcr100.dll丢失怎样修复?最新的三个修复方法可解决

最近我遇到了一个问题&#xff0c;电脑提示我缺少了msvcr100.dll文件&#xff0c;导致某些程序无法正常运行。这让我意识到了计算机中的一些系统文件的重要性&#xff0c;也让我体会到了修复这类问题的必要性。msvcr100.dll文件是Windows系统中重要的文件&#xff0c;这是一个动…

docker容器的安装(windows、linux本地安装和在线安装)

目录 一、Docker发行版本&#xff1a; 1、Windows安装Docker&#xff08;作为了解&#xff09; 2、Linux安装Docker 二、安装前准备&#xff1a; 三、默认的yum安装 四、安装docker-ce 五、阿里云镜像加速器 Docker支持在主流的操作系统平台上使用&#xff0c;包括Windo…

飞致云开源社区月度动态报告(2023年7月)

自2023年6月起&#xff0c;中国领先的开源软件公司FIT2CLOUD飞致云将以月度为单位发布《飞致云开源社区月度动态报告》&#xff0c;旨在向广大社区用户同步飞致云旗下系列开源软件的发展情况&#xff0c;以及当月主要的产品新版本发布、社区运营成果等相关信息。 飞致云开源大…