【leetcode速通java版】04——哈希表

news2024/10/5 14:29:36

前 言
🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端
☕专栏简介:代码随想录leetcode速通训练营java版本
🌰 文章简介:哈希表理论,leetcodeT242,T349,T202,T1

一、哈希表的基础理论回顾

1.哈希表主要用来解决快速获取某个元素的问题。比如查找一个学校的姓名为张三的学生,如果用数组需要的时间复杂度为O(n),但是使用哈希表的时间复杂度为O(1).

2.哈希冲突是指经过哈希计算后,其存储位置在数组的同一个物理空间。一般哈希冲突有两种解决思路:(1)拉链法 (2)线性探测法。 如果使用拉链法,需要特别注意数组的长度,避免空值过多浪费空间,也需要避免因为拉链过长导致查找元素的时间代价过高。 使用线性探测法,必须保证数组大小大于需要存储的元素大小。

二、真题特训

leetcode T242 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1: 输入: s = “anagram”, t = “nagaram” 输出: true
示例 2: 输入: s = “rat”, t = “car” 输出: false
说明: 你可以假设字符串只包含小写字母。

解法1:排序
题中问题等价于:将两个字符串排序后相等。

class Solution {
    public boolean isAnagram(String s, String t) {
        // 题解1:排序后字符串相等
        // 1. 判断长度是否相等
        if(s.length() != t.length()) 
            return false;

        // 2.转换成字符串数组
        char [] sArr= s.toCharArray();
        char [] tArr= t.toCharArray();

        // 3.排序
        Arrays.sort(sArr);
        Arrays.sort(tArr);

        // 4.比较
        return Arrays.equals(sArr, tArr);

    }
}

总结:相等是线索,进行排序把问题转换为相等问题。将问题转换为熟悉的问题处理。

复杂度分析:

  • 时间复杂度:
    在这里插入图片描述

方法二:哈希表

字母只有26个,维护一个字母频次的哈希表记录,再遍历字符串t,每出现一个字母就将频次减少1,如果有<0的频次,就说明出现了不一样的字符。

class Solution {
    public boolean isAnagram(String s, String t) {
        // 题解2:哈希表
        // 0. 字符串比较基操,判断长度
        if(s.length() != t.length())
            return false;

        // 1.构造频次哈希表
        int [] table = new int[26];
        
       // 2.记录字符串s的字母频次
      for(int i = 0; i < s.length(); i++) {
            table[s.charAt(i) - 'a']++;
        }
       

    // 3.遍历t,判断进行递减操作
    for(int j = 0; j < t.length(); j++) {
        int num = --table[t.charAt(j) - 'a'];
        if(num < 0) 
            return false;
    }

    return true;
    }
}

总结:字母数量【有限】是第二个线索,可以利用哈希表解决问题。

在这里插入图片描述

leetcodeT349 两个数组的交集

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

解法1:利用好集合

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        // 解法1 两个集合:维护两个集合,比较集合得元素是否重叠即可。
        Set<Integer> set1 = new HashSet<Integer>();
        Set<Integer> set2 = new HashSet<Integer>();

        for(int num : nums1) {
            set1.add(num);
        }

       for(int num : nums2) {
            set2.add(num);
        }


        return getIntersection(set1, set2);
    }

    int[] getIntersection(Set<Integer> set1, Set<Integer> set2) {
        // 默认set2大,最大程度压榨性能
          if (set1.size() > set2.size()) {
            return getIntersection(set2, set1);
        }

        Set<Integer> intersectionSet = new HashSet<Integer>();
       for(int num : set1) {
           if(set2.contains(num)) {
               intersectionSet.add(num);
           }
       }

        int[] result = new int[intersectionSet.size()];
        int i = 0;
        for(int num : intersectionSet) {
            result[i++] = num;
        }

        return result;
    }
}

方法二:排序 + 双指针
如果两个数组是有序的,则可以使用双指针的方法得到两个数组的交集。

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
    	// 排序
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int length1 = nums1.length, length2 = nums2.length;
        int[] intersection = new int[length1 + length2];
        int index = 0, index1 = 0, index2 = 0;
        while (index1 < length1 && index2 < length2) {
            int num1 = nums1[index1], num2 = nums2[index2];
            if (num1 == num2) {
                // 保证加入元素的唯一性
                if (index == 0 || num1 != intersection[index - 1]) {
                    intersection[index++] = num1;
                }
                index1++;
                index2++;
            } else if (num1 < num2) {
                index1++;
            } else {
                index2++;
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }
}


总结:
(1)排序是个常用中间方法。
(2)双指针适用于两个数组/集合等情况,可以一轮遍历搞定问题。

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

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

相关文章

jekyll+GithubPage搭建一个免费的个人网站

文章目录 Jekyll环境搭建windows安装RUBY、gem、Jekyll用Jekyll搭建本地博客 用jekyll模板搭建githubpage Jekyll环境搭建 windows安装RUBY、gem、Jekyll 安装ruby RUBY安装包下载地址&#xff1a;https://rubyinstaller.org/downloads/&#xff0c;一路默认选项next即可。 最…

热闻丨ChatGPT会替代你我吗?让它写了封情书后,我得到答案

ChatGPT毕竟不是人 2023年的科技圈儿被ChatGPT占据&#xff0c;上线仅仅两个月&#xff0c;活跃用户就突破一亿。上知天文下知地理&#xff0c;ChatGPT以它的强大功能让许多人生出疑问&#xff1a;ChatGPT会替代你我吗&#xff1f; 记者挑选了一些尖锐问题进行询问&#xff0…

【碳达峰碳中和】高校用电智慧监管平台的构建

摘 要&#xff1a;介绍了当前高校用电存在的问题&#xff0c;进行了原因分析&#xff0c;由此提出建立高校用电智慧监管平台。对高校用电智慧监管平台的构架进行设计&#xff0c;运用物联网技术&#xff0c;实现各回路实时自主控制&#xff0c;并细化管理权限&#xff0c;实现…

【5天打卡】学习Lodash的第一天——初体验

大家好&#xff0c;最近&#xff0c;我在学习Lodash这个工具库。Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。一款优秀的 JavaScript 工具库&#xff0c;里面包含了大量的工具函数。适用于常见浏览器以及 Node.js 等。 所以我们一起来学习Lodash&#xff0c…

7. 堆的简单学习

7. 堆 7.1 堆的定义 堆是计算机科学中一类特殊的数据结构的统称&#xff0c;堆通常可以被看做是一棵完全二叉树的数组实现。 堆的特性&#xff1a; 它是完全二叉树&#xff0c;除了树的最后一层结点不需要是满的&#xff0c;其它的每一层从左到右都是满的&#xff0c;如果最…

持续集成 在 Linux 上搭建 Jenkins,自动构建接口测试

本篇把从 0 开始搭建 Jenkins 的过程分享给大家&#xff0c;希望对小伙伴们有所帮助。 文章目录 在 Linux 上安装 Jenkins 在 Linux 上安装 Git 在 Linux 上安装 Python 在 Linux 上安装 Allure 配置 Jenkins jenkins 赋能 - 使用邮箱发送测试报告 jenkins 赋能 - 优化测试报告…

比ChatGPT更好用的Claude来了

比ChatGPT更好用的Claude来了&#xff0c;不需要魔法上网&#xff01;&#xff01;&#xff01; claude官网 点击 add to slack slack跟discord有点类似&#xff0c;先要去slack注册账号 登录之后就添加创建一个工作区 添加 不过现在已经停止添加了&#xff0c;会出现App u…

mySQL1(4/17)

目录 1. 2.字符集 3. 4.update搭配order by 和limit 5.drop table 和delete from 表名 6.主键 primary key 7.修改表 8.外键的父与子的约束关系 9.案例 10.把一个表的内容完全复制到另一个空表中去 11.更复杂的查询 12.group by 分组 13.联合查询 14.内连接和外连…

世界读书日-多读书,读好书!

我们为什么要读书&#xff0c;它可以让你在看到落日余晖的时候脑海中浮现的是“落霞与孤鹜齐飞”“秋水共长天一色”&#xff0c;而不是“哇&#xff0c;夕阳真好看”。在看到漫天飞舞的雪花时&#xff0c;能脱口而出“忽如一夜春风来&#xff0c;千树万树梨花开”&#xff0c;…

xilinx zynq+vitis实现命令行编译输出xsa以及bin文件

执行菜单命令【开始】—【所有程序】—【Xilinx Design Tools】—【Vivado2020.1】—【Vivado2020.1Tcl Shell】,弹出命令界面 或者cmd命令下输入call D:\soft_install\vivado2020.1\Vivado\2020.1\bin\vivado.bat -mode tcl 2.输入打开工程指令&#xff1a; open_project …

vue3配置router路由并实现页面跳转

1、安装vue-router 用vue3需要安装版本4.0以上的vue-router&#xff0c;安装命令&#xff1a; npm install vue-routernext --savevue2尽量安装4.0以下版本&#xff0c;安装命令&#xff1a; npm i vue-router3.1.3在package.json中可以查看vue-router版本号&#xff1a; 2、…

2399929 - 业务伙伴同步时出现错误 F2163

症状 无法保存供应商角色中业务伙伴的更改。在事务代码 MDS_PPO2 中从 BP 到供应商同步期间出现错误“尚未创建供应商 **&#xff08;错误消息&#xff1a;F2 163&#xff09;”。 环境 SAP ERP Central Component 6.0 SAP ERP 6.0 SAP ERP 的 SAP 增强包SAP ERP&#xff08…

LinkedBlockingQueue原理

1. 基本的入队出队 public class LinkedBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {static class Node<E> {E item;/*** 下列三种情况之一* - 真正的后继节点* - 自己, 发生在出队时* - null, 表…

第八章 适配器模式

文章目录 前言一、类适配器模式完整代码220V 被适配类 Voltage220V5V 适配接口 IVoltage5V适配器类转换电压 VoltageAdapter 继承220V实现5V接口手机类判断是否能充电 Phone客户端调试类适配器模式注意事项和细节 二、对象适配器模式完整代码220V 被适配类 Voltage220V5V 适配接…

Go 语言入门很简单:Go 实现简易Web应用

前言 截止到目前为止&#xff0c;几乎我们的 Go 入门文章都是在终端运行的。 在终端运行的代码或者运用运用程序只适合自己在环境搭好的环境下使用。也就是说&#xff0c;如果用户没有安装 Go 语言环境&#xff0c;是根本没法运行我们所写的 Go 代码&#xff0c;普通用户可以…

美女如何零基础学习网络安全???

学习网络安全是一项极具挑战性的技能&#xff0c;大家在自学网络安全时&#xff0c;往往会遇到各种问题&#xff0c;导致迷茫。面对这种情况&#xff0c;解决源头问题是关键。因此&#xff0c;在接下来的探讨中&#xff0c;我们将首先分析学习网络安全的常见问题&#xff0c;并…

初识Spring(普通方式Bean的读取过程)

1.SpringBoot 相⽐于 Servlet 的优点总结 1. 添加外部 jar 更容易&#xff0c;不易出错&#xff08;版本问题⽆需关注&#xff09;&#xff1b; 2. 调试项⽬更加⽅便&#xff0c;⽆需配置 Tomcat&#xff1b; 3. 发布项⽬更加⽅便&#xff0c;⽆需配置 Tomcat&#xff1b; 4. …

【iOS】—— 响应者链和事件传递链

响应者链和事件传递链 文章目录 响应者链和事件传递链二者概念响应者响应链事件UIKit继承图UIResponderUITouchUITouch几个重要属性 UITouch的两个方法&#xff08;可用于view的拖拽&#xff09; UIEventUIEvent几个重要属性 事件的产生与传递传递链传递过程hitTest:withEvent:…

多路归并排序

内部排序和外部排序 内部排序&#xff1a;整个的排序过程都在内存中进行排序 外部排序&#xff1a;对大文件进行排序&#xff0c;无法将整个需要排序的文件复制到内存&#xff0c;所以会把文件存储到外村&#xff0c;等排序时再把数据一部分一部分地调入内存进行排序&#xff…

Java基础一(String)

Java基础一(String) 概览&#xff1a; String 被声明为 final&#xff0c;因此它不可被继承。(Integer 等包装类也不能被继承&#xff09; 在 Java 8 中&#xff0c;String 内部使用 char 数组存储数据。 public final class Stringimplements java.io.Serializable, Compa…