当前位置: 首页 > article >正文

【练习】哈希表的使用

  • 🎥 个人主页:Dikz12
  • 🔥个人专栏:算法(Java)
  • 📕格言:吾愚多不敏,而愿加学
  • 欢迎大家👍点赞✍评论⭐收藏

目录

1.哈希表简介 

2.两数之和

题目描述

题解

代码实现

2.面试题.判定是否互为字符重排

题目描述 

题解 

代码实现 

3.存在重复元素

题目描述 

题解 

代码实现 

4.存在重复元素 II

题目描述 

题解 

代码实现 

5.字母异位词分组

题目描述 

题解 

代码实现 


1.哈希表简介 

  • 哈希表是什么?

存储数据的容器。

  • 有什么用 ?

快速查找某个元素,时间复杂度可以达到 O(1)。 

  • 什么时候用哈希表? 

当出现频繁查找某一个数的场景时。 

  • 怎么用哈希表? 

1.容器(哈希表 HashMap)

2.用数组模拟简易的哈希表。如:字符串中的字符,数据范围很小的时候。 

2.两数之和

题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

题解

 解法一:暴力枚举.  O(n^2)

  1. 先固定其中一个数.
  2.  依次与该数之前的数相加.

解法二: 使用哈希表来优化.  O(n)

  • 可以事先将「数组内的元素」和「下标」绑定在⼀起存⼊「哈希表」中,然后直接在哈希表中查找每⼀个元素的 target - nums[i] ,就能快速的找到⽬标和的下标.
  • 这⾥有⼀个⼩技巧,可以不⽤将元素全部放⼊到哈希表之后,再来⼆次遍历;⽽是在将元素放⼊到哈希表中的同时,直接来检查表中是否已经存在当前元素所对应的⽬标元素(即 target - nums[i] )。                                                                                                                              

代码实现

    public int[] twoSum(int[] nums, int target) {
        //<value, i>
        Map<Integer, Integer> hash = new HashMap<>();

        for(int i = 0; i < nums.length; i++) {
            int ret = target - nums[i];
            if(hash.containsKey(ret)) {
                return new int[]{i, hash.get(ret)};
            }
            hash.put(nums[i], i);
        }
        return new int[]{-1, -1};
    }

2.面试题.判定是否互为字符重排

题目描述 

题解 

解法:使用哈希表. 

算法思路:
  1. 当两个字符串的⻓度不相等的时候,是不可能构成互相重排的,直接返回 false
  2. 如果两个字符串能够构成互相重排,那么每个字符串中各个字符出现的次数⼀定是相同 的。因此,我们可以分别统计出这两个字符串中各个字符出现的次数,然后逐个⽐较是否相等即可。这样的话,我们就可以选择「哈希表」来统计字符串中字符出现的次数。

代码实现 

    public boolean CheckPermutation(String s1, String s2) {
        if(s1.length() != s2.length()) {
            return false;
        }
        int[] hash = new int[26];
        //先把第一个字符串信息统计到哈希表中
        for(int i = 0; i < s1.length(); i++) {
            hash[s1.charAt(i) - 'a']++;
        }

        for(int j = 0; j < s2.length(); j++) {
            hash[s2.charAt(j) - 'a']--;
            if(hash[s2.charAt(j) - 'a'] < 0) {
                return false;
            }
        }
        return true;
    }

3.存在重复元素

题目描述 

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

示例 1:

输入:nums = [1,2,3,1]
输出:true

示例 2:

输入:nums = [1,2,3,4]
输出:false

题解 

算法思路:(和两数之和的逻辑一样)

  • 仅需在遍历数组的过程中,检查当前元素「是否在之前已经出现过」即可。  
  • 可以利⽤哈希表,仅需存储数「组内的元素」。在遍历数组的时候,⼀边检查哈希表中是否
    已经出现过当前元素,⼀边将元素加⼊到 哈希表中。

代码实现 

    public boolean containsDuplicate(int[] nums) {
        Set<Integer> hash = new HashSet<>();

        for(int i = 0; i < nums.length; i++) {
            if(hash.contains(nums[i])) {
                return true;
            }
            hash.add(nums[i]);
        }
        return false;
    }

4.存在重复元素 II

题目描述 

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [1,2,3,1], k = 3
输出:true

示例 3:

输入:nums = [1,2,3,1,2,3], k = 2
输出:false

题解 

算法思路:
解决该问题需要我们快速定位到两个信息:
  • 两个相同的元素;
  • 这两个相同元素的下标。
因此,我们可以使⽤「哈希表」,令数组内的元素做 key 值,该元素所对应的下标做 val 值,将
「数组元素」和「下标」绑定在⼀起,存⼊到「哈希表」中。

代码实现 

    public boolean containsNearbyDuplicate(int[] nums, int k) {
        Map<Integer, Integer> hash = new HashMap<>();

        for(int i = 0; i < nums.length; i++) {
            
            if(hash.containsKey(nums[i])) {
                int ret = hash.get(nums[i]);
                if(i - ret <= k) {
                    return true;
                }
            }
            hash.put(nums[i], i);
        }
        return false;

    }

5.字母异位词分组

题目描述 

题解 

算法思路:
互为字⺟异位词的单词有⼀个特点:将它们 排序 之后,两个单词应该是 完全相同 的。 所以,我们可以利⽤这个特性,将单词按照字典序排序,如果排序后的单词相同的话,就划分到同⼀ 组中。
利⽤语⾔提供的「容器」的强⼤的功能就能实现这两点:
  • 将排序后的字符串( string )当做哈希表的 key 值;
  • 将字⺟异位词数组( string[] )当成 val 值。

代码实现 

    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> hash = new HashMap<>();

        for(String s : strs) {
            char[] tmp = s.toCharArray();
            //排序
            Arrays.sort(tmp);
            String key = new String(tmp);
            //哈希表中不存在
            if(!hash.containsKey(key)) {
                hash.put(key, new ArrayList());
            }
            //存在
            hash.get(key).add(s);
        }
        //提取结果
        return new ArrayList(hash.values());
    }

http://www.kler.cn/a/282057.html

相关文章:

  • R语言-快速对多个变量取交集
  • spi 回环
  • vue实现展示并下载后端返回的图片流
  • 微博短链接平台-项目测试用例设计(Xmind)
  • 基于Spring Boot+Unipp的博物馆预约小程序(协同过滤算法、二维码识别)【原创】
  • 解决微信小程序自定义tabbar点击两次才能跳转
  • macOS 设置 vm.max_map_count [RAGFlow]
  • 刘文超行测笔记
  • Dopamine(多巴胺)越狱工具一键越狱教程:支持 iOS 15-iOS 16.6.1 设备
  • 5G NR HARQ操作机制
  • MySQL索引(三)
  • 图像搜索引擎DIY【CLIP+FAISS】
  • 力扣231题详解:2的幂的多种解法与模拟面试问答
  • DrawDB数据库设计工具本地部署结合内网穿透实现团队异地协作办公
  • Ubuntu22.04安装深度学习的GPU环境详细教程(小白图文,显卡驱动、CUDA、cuDNN、PyTorch一步到位)
  • Scrapy 项目部署Scrapyd
  • WHAT - 通过 react-use 源码学习 React(State 篇)
  • html+css+js网页设计 婚庆类型模版 12个页面
  • 关于复杂业务逻辑使用SQL还是java代码实现的思考
  • Golang安装与环境配置
  • 严重腰椎滑脱、无法走路,江山邦尔骨科医院机器人辅助手术为患者完美复位
  • XML 数据格式介绍及其应用
  • 1.5.1、输入输出技术
  • 【编程知识】c++中的结构体和JavaScript中的对象有啥异同
  • 树上dp+分组背包类问题
  • SpringIoc体系结构设计