Hash表算法

哈希表

  • 理论知识(本文来自于代码随想录摘抄)
    • 什么是哈希
    • 常见的三种哈希结
      • 数组:
      • set:
      • map:
      • 其他常用方法或者技巧(自己总结的)
    • 练习题和讲解
      • 有效的字母移位词
      • 349. 两个数组的交集
      • 1. 两数之和
      • 454. 四数相加 II
      • 15. 三数之和
    • 总结

理论知识(本文来自于代码随想录摘抄)

什么是哈希

哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素,如下图所示:
在这里插入图片描述
那么哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里

常见的三种哈希结

当我们想使用哈希法来解决问题的时候,我们一般会选择如下三种数据结构。
数组
set (集合)
map(映射)

数组:

当目标的范围是已知的,是小的,我们会使用数组。(经常使用,所以少介绍。)

set:

在这里插入图片描述

map:

在这里插入图片描述

其他常用方法或者技巧(自己总结的)

在这里插入图片描述
10,用来判断某个值是否存在哈希表中:containsKey()

if(result.containsKey(temp)){}

练习题和讲解

有效的字母移位词

使用int
前置知识:
字母a-z,A-Z的ASCII码是连续的。
所以’a’-‘a’=0;‘z’-‘a’=25;
在这里插入图片描述

class Solution {
    public boolean isAnagram(String s, String t) {
        int[] arr=new int[26];              //用来存储26个字母出现的次数
        for(int i=0;i<s.length();i++){      //字符串用length()方法,数组为length。因为对于字符串,length是方法,数组是内置属性。    
        arr[s.charAt(i)-'a']++;             //charAt(i)获取字符串中i位置的字符。  我们在对于的下标的位置+1.比如出现z,则是'z'-'a',在25这个位置+1.
        };
        for(int i=0;i<t.length();i++){
            arr[t.charAt(i)-'a']--;         //目的同样,在对应位置-1,抵消s字符串中出现的字母。
        };
        for(int a:arr){                     //增强for循环方法。
            if(a!=0){                       //进行判断,如果不等0,证明两个里面的出现字母的数量不一致。
                return false;
            }
        }
        return true;
    }
}

349. 两个数组的交集

349. 两个数组的交集
使用set

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
            return new int[0];
        }                   //首先判断是否为空
        Set<Integer> set1 = new HashSet<>();        //使用set可以直接去重
        Set<Integer> resSet = new HashSet<>();
        //遍历数组1
        for (int i : nums1) {
            set1.add(i);    
        }
        //遍历数组2的过程中判断哈希表中是否存在该元素
        for (int i : nums2) {
            if (set1.contains(i)) {         //contains() 判断这个值是否在哈希表中
                resSet.add(i);
            }
        }
        
        //另外申请一个数组存放setRes中的元素,最后返回数组
        int[] arr = new int[resSet.size()];
        int j = 0;
        for(int i : resSet){
            arr[j++] = i;
        }
        
        return arr;
    }
}

1. 两数之和

1. 两数之和
使用map(需要存放 key value)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 创建一个 HashMap 来存储数字及其对应的索引
        Map<Integer, Integer> map = new HashMap<>();
        int n = nums.length;
        
        // 遍历数组
        for (int i = 0; i < n; i++) {
            // 计算当前元素的补数
            int temp = target - nums[i];
            // 检查补数是否在 HashMap 中
            if (map.containsKey(temp)) {
                // 找到结果,那么返回当前索引和补数的索引
                return new int[]{map.get(temp), i};
            }
            // 如果没有找到补数,就把当前数字和它的索引放入 HashMap
            map.put(nums[i], i);
        }
        // 如果没有找到,返回一个空数组,考虑到题目保证有解这里可以省略
        return new int[]{};
    }
}

454. 四数相加 II

454. 四数相加 II

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int res = 0;
        //不仅要保存值,还需要保存其出现次数,所以使用map(key,value)来进行存储数据。
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        //统计两个数组中的元素之和,同时统计出现的次数,放入map
        for (int i : nums1) {
            for (int j : nums2) {
                int sum = i + j;
                map.put(sum, map.getOrDefault(sum, 0) + 1);//getOrDefault这个的意思是,如果存在,返回存在的值,不存在返回default0
            }
        }
        //统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
        for (int i : nums3) {
            for (int j : nums4) {
                //因为本题不去重,所以有不同组合,需要统计的值为 res+sum(对应的值);
                res += map.getOrDefault(0 - i - j, 0);
            }
        }
        return res;
    }
}

15. 三数之和

15. 三数之和

使用哈希集合:

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
	List<List<Integer>> result = new ArrayList<>();
	Arrays.sort(nums);

	for (int i = 0; i < nums.length; i++) {
		// 如果第一个元素大于零,不可能凑成三元组
		if (nums[i] > 0) {
			return result;
		}
		// 三元组元素a去重
		if (i > 0 && nums[i] == nums[i - 1]) {
			continue;
		}

		HashSet<Integer> set = new HashSet<>();
		for (int j = i + 1; j < nums.length; j++) {
			// 三元组元素b去重
			if (j > i + 2 && nums[j] == nums[j - 1] && nums[j - 1] == nums[j - 2]) {
				continue;
			}

			int c = -nums[i] - nums[j];
			if (set.contains(c)) {
				result.add(Arrays.asList(nums[i], nums[j], c));
				set.remove(c); // 三元组元素c去重
			} else {
				set.add(nums[j]);
			}
		}
	}
	return result;
    }
}

使用双指针(更为推荐)

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        //二维集合,因为不止一个集合
            List<List<Integer>> ans=new ArrayList();
            int len=nums.length;

        //如果值小于3,则没有意义
            if(len<3||nums==null) return ans;

        //排序,更方便我们双指针的移动
            Arrays.sort(nums);

        //定i的位置,然后动left和right两个指针的位置来凑0
        for(int i=0;i<len;i++){
        //如果第一个i都>0,则不可能三数之和为0
            if(nums[i]>0) break;
        //题目去重,所以我们判断前一位值如果等于后一位,则跳过。
            if(i>0&&nums[i]==nums[i-1]) continue;
        //定义左右指针    
            int L=i+1;
            int R=len-1;   
            while(L<R){
                int sum =nums[i]+nums[R]+nums[L];
        //如果相等,则添加进入二维数组中
                if(sum==0){
                    ans.add(Arrays.asList(nums[i],nums[L],nums[R]));
        //归零
                    while(L<R&& nums[L]==nums[L+1]) L++;
                    while(L>R&& nums[R]==nums[R-1]) R--;
                    L++;
                    R--;
                }
        //和小,就左指针右移,和大,就右指针左移
                else  if(sum<0)L++;
                else if(sum>0)R--;
            }
        }
        //返回二维数组。
        return ans;
    }
}

总结

哈希表理论基础
在关于哈希表,你该了解这些! (opens new window)中,我们介绍了哈希表的基础理论知识,不同于枯燥的讲解,这里介绍了都是对刷题有帮助的理论知识点。

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

对于哈希表,要知道哈希函数和哈希碰撞在哈希表中的作用。

哈希函数是把传入的key映射到符号表的索引上。

哈希碰撞处理有多个key映射到相同索引上时的情景,处理碰撞的普遍方式是拉链法和线性探测法。

接下来是常见的三种哈希结构:

数组
set(集合)
map(映射)
在C++语言中,set 和 map 都分别提供了三种数据结构,每种数据结构的底层实现和用途都有所不同,在关于哈希表,你该了解这些! (opens new window)中我给出了详细分析,这一知识点很重要!

例如什么时候用std::set,什么时候用std::multiset,什么时候用std::unordered_set,都是很有考究的。

只有对这些数据结构的底层实现很熟悉,才能灵活使用,否则很容易写出效率低下的程序。

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

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

相关文章

Java SPI 机制详解

面向对象设计鼓励模块间基于接口而非具体实现编程&#xff0c;以降低模块间的耦合&#xff0c;遵循依赖倒置原则&#xff0c;并支持开闭原则&#xff08;对扩展开放&#xff0c;对修改封闭&#xff09;。然而&#xff0c;直接依赖具体实现会导致在替换实现时需要修改代码&#…

宇音天下最新力作 | VTX356语音识别合成芯片问世

北京宇音天下科技有限公司&#xff0c;依托在语音技术领域的丰富经验和技术积累&#xff0c;成功推出了一款具有里程碑意义的语音识别合成芯片——VTX356。这款芯片的问世&#xff0c;不仅彰显了公司在智能语音处理领域的专业实力&#xff0c;也预示着智能家居、车载电子、智能…

51c视觉~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/11474386 #HAFormer 融合 CNN 与 Transformer 的高效轻量级语义分割模型 HAFormer以最小的计算开销和紧凑的模型尺寸实现了高性能&#xff0c;在Cityscapes上的mIoU达到了74.2%&#xff0c;在CamVid测试数据集上的mIoU达到…

Spring Boot集成Milvus和deeplearning4j实现图搜图功能

1.什么是Milvus&#xff1f; Milvus 是一种高性能、高扩展性的向量数据库&#xff0c;可在从笔记本电脑到大型分布式系统等各种环境中高效运行。它既可以开源软件的形式提供&#xff0c;也可以云服务的形式提供。 Milvus 是 LF AI & Data Foundation 下的一个开源项目&…

[含文档+PPT+源码等]精品基于PHP实现的培训机构信息管理系统的设计与实现

基于PHP实现的培训机构信息管理系统的设计与实现背景&#xff0c;可以从以下几个方面进行阐述&#xff1a; 一、社会发展与教育需求 随着经济的不断发展和人口数量的增加&#xff0c;教育培训行业迎来了前所未有的发展机遇。家长对子女教育的重视程度日益提高&#xff0c;课外…

wireshark筛选条件整理

Wireshark筛选条件整理 一、MAC地址过滤二、IP地址过滤三、端口过滤四、协议筛选五、数据分析1、整体2、frame数据帧分析3、 Ethernet II 以太网4、IP协议5、TCP6、HTTP7、ARP8、DLEP动态链接交换协议 六、统计-协议分级&#xff08;统计包占比&#xff09; and && 、 …

通俗直观介绍ChatGPT背后的大语言模型理论知识

“AI 的 iPhone 时刻到来了”。非算法岗位的研发同学’被迫’学习 AI&#xff0c;产品岗位的同学希望了解 AI。但是&#xff0c;很多自媒体文章要么太严谨、科学&#xff0c;让非科班出身的同学读不懂&#xff1b;要么&#xff0c;写成了科幻文章&#xff0c;很多结论都没有充分…

『完整代码』宠物召唤

创建脚本并编写&#xff1a;PetFollowTarget.cs using UnityEngine; public class PetFollowTarget : MonoBehaviour{Transform target;float speed 2f;Animator animator;void Start(){target GameObject.Find("PlayerNormal/PetsSmallPos").gameObject.transform…

macOS 15 Sequoia dmg格式转用于虚拟机的iso格式教程

想要把dmg格式转成iso格式&#xff0c;然后能在虚拟机上用&#xff0c;最起码新版的macOS镜像是不能用UltraISO&#xff0c;dmg2iso这种软件了&#xff0c;你直接转放到VMware里绝对读不出来&#xff0c;办法就是&#xff0c;在Mac系统中转换为cdr&#xff0c;然后再转成iso&am…

【MySQL备份】使用XtraBackup搭建GTID主从复制

创建备份账号 这里给了all 权限 grant all on *.* to backup% identified by backup; 在主库上进行全备 xtrabackup --defaults-file/home/storage/mysql_3306/mysql_3306.cnf --backup --userbackup --passwordbackup --port3306 --target-dir/home/backups/all_xtrabp 备…

java中Scanner的nextLine和next方法

思考&#xff0c;输入1 2 3 4 5加上enter&#xff0c;输出什么 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int[][] m new int[2][2];for (int i 0; i < 2; i) {for (int j 0; j < 2;…

DEVOPS: 容器与虚拟化与云原生

概述 传统虚拟机&#xff0c;利用 hypervisor&#xff0c;模拟出独立的硬件和系统&#xff0c;在此之上创建应用虚拟机是一个主机模拟出多个主机虚拟机需要先拥有独立的系统docker 是把应用及配套环境独立打包成一个单位docker 是在主机系统中建立多个应用及配套环境docker 是…

OKCC的API接口与SDK的区别

随着累计的客户越来越多&#xff0c;客户的多元化就成了必然。以前最早我们的客户群体占比最大的可能是话务运营这个圈子。但是现在很多企业软件开发公司也成为了合作伙伴&#xff0c;那么这种就不是简单的搭建一套OKCC系统&#xff0c;然后配上线路就完成了&#xff0c;而是要…

大数据新视界 -- 大数据大厂之大数据重塑影视娱乐产业的未来(4 - 4)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

鸿蒙的底部菜单导航实现

开始入坑鸿蒙 效果图图下&#xff1a; Index代码如下: import Home from "../pages/home/Home" //首页 import Classify from "./classify/Classify" //分类 import Mine from "../pages/mine/Mine" //我的 Entry Component struct Index {Sta…

实现企业微信打卡月报与简道云的高效集成

实现企业微信打卡月报与简道云的高效集成 企业微信打卡月报同步到简道云 在企业管理中&#xff0c;员工的考勤数据是至关重要的一环。为了实现高效的数据管理和分析&#xff0c;我们需要将企业微信的打卡月报数据集成到简道云平台。本文将分享一个具体的技术案例&#xff0c;展…

【力扣专题栏】两两交换链表中的节点,如何实现链表中两两相邻节点的交换?

这里写目录标题 1、题目描述解释2、算法原理解析3、代码编写 1、题目描述解释 2、算法原理解析 3、代码编写 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int…

前端经典【面试题】持续更新HTML、CSS、JS、VUE、FLUTTER、性能优化等

HTML/CSS 面试题 什么是语义化 HTML&#xff1f; 说明&#xff1a;语义化 HTML 使用 HTML 标签来描述内容的含义&#xff0c;而不仅仅是其外观。使用语义化标签可以提高可读性和可访问性&#xff0c;并对 SEO 友好。示例&#xff1a; <header><h1>网站标题</h1&…

Qt/C++ 调用迅雷开放下载引擎(ThunderOpenSDK)下载数据资源

目录导读 前言ThunderOpenSDK 简介参考 xiaomi_Thunder_Cloud 示例ThunderOpenSDK 下载问题 前言 在对以前老版本的exe执行程序进行研究学习的时候&#xff0c;发现以前的软件是使用的ThunderOpenSDK这个迅雷开放下载引擎进行的项目数据下载&#xff0c;于是在网上搜索一番找到…

ML2021Spring-hw1(COVID-19 Cases Prediction)

文章目录 前言代码一代码二对比 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本篇博客内容来自&#xff1a;Machine Learning 2022 Spring &#x1f4ab;更多和本篇博客相关内容详见专栏&#xff1a;Machine Learning(李…