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

哈希表

首先什么是 哈希表,哈希表(英文名字为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.mfbz.cn/a/54055.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

29.利用fminbnd 求解 最大容积问题(matlab程序)

1.简述 用于求某个给定函数的最小值点。 使用方法是&#xff1a; xfminbnd(func,x1,x2) func是函数句柄&#xff0c;然后x1和x2就是函数的区间&#xff0c;得到的结果就是使func取最小值的x值 当然也可以使用[x,fv]fminbnd(func,x1,x2)的方式&#xff0c;这个时候fv就是函数…

Web3.0:已经开启的互联网革命!

1 痛点 2 web发展形态 只读、封闭式、协作式。 3 一个高度联系、全球统一的数字经济体 去中心化架构通过计算几余打破数据垄断&#xff0c;同时实现数字确权大量的功能依靠智能合约自动实现&#xff0c;运转效率大大提升DAO大量涌现&#xff0c;全球范围实现资源配置 4 特…

MAC电脑设置charles,连接手机的步骤说明(个人实际操作)

目录 一、charles web端设置 1. 安装charles之后&#xff0c;先安装证书 2. 设置 Proxy-Proxy Settings 3. 设置 SSL Proxying 二、手机的设置 1. 安卓 2. ios 资料获取方法 一、charles web端设置 1. 安装charles之后&#xff0c;先安装证书 Help-SSL Proxying-Inst…

我的第一个前端(VS code ,Node , lite-server简易服务器,npm 运行)

第一种方式&#xff1a;使用Visual Studio Code创建并运行 第一个前端项目的步骤&#xff0c;如下&#xff1a; 1. 下载和安装Visual Studio Code&#xff1a; 访问Visual Studio Code官方网站&#xff08;Visual Studio Code - Code Editing. Redefined&#xff09;并根据你…

基于x-scan扫描线的3D模型渲染算法

基于x-scan算法实现的z-buffer染色。c#语言&#xff0c;.net core framework 3.1运行。 模型是读取3D Max的obj模型。 x-scan算法实现&#xff1a; public List<Vertex3> xscan() {List<Vertex3> results new List<Vertex3>();SurfaceFormula formula g…

算法通关村第三关——双指针的妙用

双指针思想 快慢指针 所谓的双指针其实就是两个变量。双指针思想简单好用&#xff0c;在处理数组、字符串等场景下很常见。看个例子&#xff0c;从下面序列中删除重复元素[1,2,2,2,3,3,3,5,5,7,8]&#xff0c;重复元素只保留一个。删除之后的结果应该为[1,2,3,5,7,8]。我们可以…

应用程序接口(API)安全的入门指南

本文简单回顾了 API 的发展历史&#xff0c;其基本概念、功能、相关协议、以及使用场景&#xff0c;重点讨论了与之相关的不同安全要素、威胁、认证方法、以及十二项优秀实践。 根据有记录的历史&#xff0c;随着 Salesforce 的销售自动化解决方案的推出&#xff0c;首个 Web A…

HCIP期中实验

考试需求 1 、该拓扑为公司网络&#xff0c;其中包括公司总部、公司分部以及公司骨干网&#xff0c;不包含运营商公网部分。 2 、设备名称均使用拓扑上名称改名&#xff0c;并且区分大小写。 3 、整张拓扑均使用私网地址进行配置。 4 、整张网络中&#xff0c;运行 OSPF 协议…

PostgreSQL中如何配置Huge page的数量

在了解如在PG中如何配置大页之前&#xff0c;我们先要对大页进行一定的了解&#xff0c;为什么要配置大页&#xff0c;配置大页的好处有哪些。 我们日常的操作系统中&#xff0c;程序不直接使用内存&#xff0c;而是使用虚拟内存地址来处理内存分配&#xff0c;避免计算的复杂…

1.3 eureka+ribbon,完成服务注册与调用,负载均衡源码追踪

本篇继先前发布的1.2 eureka注册中心&#xff0c;完成服务注册的内容。 目录 环境搭建 采用eurekaribbon的方式&#xff0c;对多个user服务发送请求&#xff0c;并实现负载均衡 负载均衡原理 负载均衡源码追踪 负载均衡策略 如何选择负载均衡策略&#xff1f; 饥饿加载…

windows下tomcat无故宕机,检测http或https服务,并自动重启Tomcat服务

一、问题描述及解决原理 把项目发布到windows服务器中&#xff0c;如tomcat工程不稳定&#xff0c;会有无故宕机的问题。如果通过程序无法解决&#xff0c;并且重启tomcat服务能够生效的话&#xff0c;可以做一个自动检测并重启的脚本。 脚本通过检测tomcat对应的工程链接&…

一文了解Angular、React 和 Vue.js的区别

前端开发人员在开始一个新项目时首先要回答的问题是&#xff1a;我应该选择哪个框架&#xff1f; 哪个框架更适合我的需求&#xff1f; 在本文中&#xff0c;我们将向您快速概述当前使用的最常见的前端框架&#xff0c;旨在帮助您选择最能满足您需求的框架。这些框架是 Angular…

【雕爷学编程】Arduino动手做(177)---ESP-32 掌控板

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

PHP8的常量-PHP8知识详解

常量和变量是构成PHP程序的基础&#xff0c;在PHP8中常量的这一节中&#xff0c;主要讲到了定义常量和预定义常量两大知识点。 一、定义常量 定义常量也叫声明常量。在PHP8中&#xff0c;常量就是一个标识符&#xff08;名字&#xff09;&#xff0c;一旦定义&#xff08;声明&…

Java常用API:Math、Syetem、Runtime、BigDecimal

Math类 //目标:了解下Nath类提供的常见方法。 // 1、public static int abs(int a):取绝对值&#xff08;拿到的结果一定是正数&#xff09; //public static double abs(double a) system.out.println(Math.abs(-12)); // 12 system.out.println(Math.abs(123));// 123 system…

VScode远程不用再输入密码操作

安装插件remote development 1.先检查自己电脑上有没有生成一对公钥和私钥。&#xff08;一般会在这个目录&#xff09; 如果没有的话就自己生成一下。 打开命令行输入以下命令 ssh-keygen -t rsa2.在虚拟机中先看一下有没有公钥和私钥。如果没有的话就自己生成一下。 打开…

华为数通HCIA-网络参考模型(TCP/IP)

网络通信模式 作用&#xff1a;指导网络设备的通信&#xff1b; OSI七层模型&#xff1a; 7.应用层&#xff1a;由应用层协议&#xff08;http、FTP、Telnet.&#xff09;为应用程序产生对应的数据&#xff1b; 6.表示层&#xff1a;将应用层产生的数据转换成网络设备看得懂…

STM32 USB使用记录:HID类设备(后篇)

文章目录 目的基础说明项目构建与代码调整接收发送代码与测试示例链接报告描述符总结 目的 接上篇&#xff1a; 《STM32 USB使用记录&#xff1a;HID类设备&#xff08;前篇&#xff09;》 USB HID 类的设备有个比较大的好处是大部分时候接入主机中都是可以免驱使用的。这篇文…

Shell脚本实现分库分表操作

目录 一&#xff0c;分库备份 二&#xff0c;分库操作 三&#xff0c;分库分表备份 四&#xff0c;备份还原 一&#xff0c;分库备份 #!/bin/bash mysql_cmd-uroot -pzly666666 bak_path/backup/db [ -d ${bak_path} ] || mkdir -p ${bak_path}mysql ${mysql_cmd} -e show…

【图论】BFS中的最短路模型

算法提高课笔记 目录 单源最短路迷宫问题题意思路代码 武士风度的牛题意思路代码 抓住那头牛题意思路代码 多源最短路矩阵距离题意思路代码 双端队列BFS电路维修题意思路代码&#xff08;加了注释&#xff09; BFS可以解决边权为1的最短路问题&#xff0c;下面是相关例题 单源…