数据结构-哈西表笔记

news2024/10/5 12:32:33

自定义26位字母哈西表

有效的字母异位词

242. 有效的字母异位词 - 力扣(LeetCode)

class Solution {
    public boolean isAnagram(String s, String t) {

        // 获取字符串 s 和 t 的长度
        int sLen = s.length();
        int tLen = t.length();

        // 如果两个字符串的长度不相等,则它们不可能是字母异位词
        if (sLen != tLen) {
            return false;
        }

        // 创建一个大小为 26 的数组 count 来统计每个字母出现的次数
        // 数组的索引 0-25 对应字母 'a'-'z'
        int count[] = new int[26];

        // 遍历字符串 s,并更新 count 数组
        // 对于 s 中的每个字符,计算其相对于 'a' 的索引位置,并将该位置的计数器加 1
        for (int i = 0; i < sLen; i++) {
            count[s.charAt(i) - 'a']++;
        }

        // 遍历字符串 t,检查每个字符在 count 数组中的计数
        for (int i = 0; i < tLen; i++) {
            // 如果 t 中的某个字符的计数已经为 0 或小于 0,说明它在 s 中不存在
            // 或者 s 中该字符出现的次数不足,直接返回 false
            if (count[t.charAt(i) - 'a'] <= 0) {
                return false;
            }
            // 对于 t 中的每个字符,计算其索引位置,并将该位置的计数器减 1
            count[t.charAt(i) - 'a']--;
        }

        // 如果所有字符的出现次数都能相互抵消,说明 s 和 t 是字母异位词
        return true;
    }
}

赎金信

383. 赎金信 - 力扣(LeetCode)

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        
        // 不需要检查长度是否相等,题目并未要求
        int[] map = new int[26]; // 长度为26的数组,用于记录字符次数

        // 遍历 `magazine`,将每个字符出现的次数记录到 `map` 中。
        for(int i = 0; i < magazine.length(); i++){
            map[magazine.charAt(i) - 'a']++;  // 累加 magazine 中字符的出现次数
        }

        // 遍历 `ransomNote`,减少对应字符的计数。
        for(int i = 0; i < ransomNote.length(); i++){
            map[ransomNote.charAt(i) - 'a']--; // 减少 ransomNote 中字符的计数
            // 如果某个字符在 `magazine` 中的数量不足以构造 `ransomNote`,返回 false
            if(map[ransomNote.charAt(i) - 'a'] < 0){
                return false;
            }
        }

        return true; // 能够成功构造则返回 true
    }
}

java自带hashset

两个数组的交集

349. 两个数组的交集 - 力扣(LeetCode)

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {

        // 创建一个 HashSet 存储 nums1 中的所有元素,避免重复
        Set<Integer> hashset1 = new HashSet<>();
        // 创建另一个 HashSet 存储 nums2 中与 nums1 交集的元素
        Set<Integer> hashset2 = new HashSet<>();

        // 遍历 nums1 数组,并将其所有元素添加到 hashset1 中
        for (int i = 0; i < nums1.length; i++) {
            hashset1.add(nums1[i]);  // HashSet 自动去重
        }

        // 遍历 nums2 数组,检查 hashset1 是否包含 nums2 中的元素
        // 如果包含,则该元素为交集,将其添加到 hashset2 中
        for (int i = 0; i < nums2.length; i++) {
            if (hashset1.contains(nums2[i])) {
                hashset2.add(nums2[i]);  // 只添加交集部分的元素
            }
        }

        // 将 hashset2 中的元素转换为数组形式,返回交集结果
        int ret[] = new int[hashset2.size()];  // 初始化结果数组,大小为交集元素的个数
        int i = 0;
        for (int temp : hashset2) {
            ret[i] = temp;  // 将 HashSet 中的元素逐一存入数组
            i++;
        }

        return ret;  // 返回最终的交集数组
    }
}

快乐数

202. 快乐数 - 力扣(LeetCode)

class Solution {
    public boolean isHappy(int n) {

        // 创建一个 HashSet 来记录已经计算过的数字,防止进入无限循环
        Set<Integer> hashset = new HashSet<>();

        // 循环条件:n 不等于 1 且 n 不在 hashset 中时继续循环
        while (n != 1 && !hashset.contains(n)) {
            // 将当前数字 n 加入 hashset,表示已经访问过
            hashset.add(n);
            // 计算 n 的各位数字的平方和,更新 n
            n = isHappySum(n);
        }

        // 如果最终 n 等于 1,则返回 true,表示该数字是快乐数;否则返回 false
        return n == 1;
    }

    // 计算数字 n 的各位数字平方和的函数
    int isHappySum(int n) {
        int sum = 0;
        // 当 n > 0 时,不断取出各位数字并计算它们的平方
        while (n > 0) {
            int temp = n % 10;  // 取出 n 的最后一位数字
            sum += temp * temp;  // 计算该位数字的平方并累加到 sum
            n /= 10;  // 去掉最后一位数字
        }
        // 返回各位数字平方和
        return sum;
    }
}

哈希表HashMap

两数之和

1. 两数之和 - 力扣(LeetCode)

import java.util.HashMap;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 创建一个长度为2的数组,用于存放结果
        int ret[] = new int[2];

        // 创建一个哈希表,用于存储数组元素及其对应的索引
        HashMap<Integer, Integer> map = new HashMap<>();

        // 遍历输入数组,将每个元素及其索引存入哈希表
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i], i);
        }

        // 再次遍历输入数组,寻找两个数的和等于目标值
        for (int i = 0; i < nums.length; i++) {
            // 计算当前元素所需的另一半
            int temp = target - nums[i];

            // 检查哈希表中是否存在另一半,且它的索引不是当前元素的索引
            if (map.containsKey(temp) && map.get(temp) != i) {
                // 找到满足条件的两个元素,存入结果数组
                ret[0] = i;               // 当前元素的索引
                ret[1] = map.get(temp);  // 另一半的索引
                break;                   // 找到结果后跳出循环
            }
        }

        return ret; // 返回结果数组
    }
}

四数相加II

454. 四数相加 II - 力扣(LeetCode)

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        // 创建一个 HashMap 用于存储 nums1 和 nums2 的所有可能和及其出现的次数
        HashMap<Integer, Integer> map = new HashMap<>();
        int ret = 0; // 用于存储符合条件的四元组数量

        // 遍历 nums1 和 nums2 以计算所有可能的和
        for (int i = 0; i < nums1.length; i++) {
            for (int j = 0; j < nums2.length; j++) {
                // 计算 nums1[i] 和 nums2[j] 的和
                int temp = nums1[i] + nums2[j];
                // 如果 map 中已经存在该和,则将其计数加一
                if (map.containsKey(temp)) {
                    map.put(temp, map.get(temp) + 1);
                } else {
                    // 否则,将该和加入 map,并初始化计数为 1
                    map.put(temp, 1);
                }
            }
        }

        // 遍历 nums3 和 nums4 以查找与 map 中的和匹配的元素
        for (int i = 0; i < nums3.length; i++) {
            for (int j = 0; j < nums4.length; j++) {
                // 计算 - (nums3[i] + nums4[j]),以便与 map 中的和进行匹配
                int temp = -nums3[i] - nums4[j];
                // 如果 map 中存在这个和,则将该和对应的计数加到 ret 中
                if (map.containsKey(temp)) {
                    ret += map.get(temp);
                }
            }
        }

        // 返回符合条件的四元组的总数
        return ret;
    }
}

双指针

三数之和(难)

难在去重。如果不用去重就可以用哈希表

15. 三数之和 - 力扣(LeetCode)

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 初始化结果列表,用来存储所有符合条件的三元组
        List<List<Integer>> ret = new ArrayList<>();

        // 首先对输入数组进行排序,这样我们可以利用排序后的性质来避免重复和进行双指针操作
        Arrays.sort(nums);

        // 遍历排序后的数组,i 是第一个选定的数,遍历数组中所有可能的第一个数
        for (int i = 0; i < nums.length; i++) {
            // 如果当前数大于0,则没有必要继续查找,因为在排序数组中,后续的数也都大于0,三数之和不可能为0
            if (nums[i] > 0) {
                break;
            }

            // 跳过重复的数值,避免结果中出现重复的三元组
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            // 设置双指针,left 指向当前数之后的元素,right 指向数组末尾
            int left = i + 1;
            int right = nums.length - 1;

            // 使用双指针方法寻找三个数的和为0的组合
            while (left < right) {
                // 计算当前三个数的和
                int sum = nums[i] + nums[left] + nums[right];

                // 如果和大于0,说明右指针处的数太大,需要左移右指针
                if (sum > 0) {
                    right--;
                // 如果和小于0,说明左指针处的数太小,需要右移左指针
                } else if (sum < 0) {
                    left++;
                // 如果和等于0,找到了一个符合条件的三元组
                } else {
                    // 将找到的三元组加入结果列表
                    ret.add(Arrays.asList(nums[i], nums[left], nums[right]));

                    // 为了避免重复的三元组,继续移动左指针,跳过所有重复的左边元素
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++;
                    }

                    // 同样,继续移动右指针,跳过所有重复的右边元素
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--;
                    }

                    // 在找到一个三元组后,继续尝试其他可能性,因此移动双指针
                    left++;
                    right--;
                }
            }
        }
        // 返回所有找到的不重复的三元组
        return ret;
    }
}

四数之和(难)

. - 力扣(LeetCode)

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        // 这个列表将存储最终的四元组结果
        List<List<Integer>> ret = new ArrayList<>();
        
        // 排序输入数组,以便于避免重复并使用双指针技术
        Arrays.sort(nums);

        // 遍历数组,选择四元组中的第一个数字
        for (int i = 0; i < nums.length; i++) {
            // 如果当前数字大于目标值且非负,可以提前结束
            if (nums[i] > target && nums[i] >= 0) {
                break;
            }
            
            // 跳过第一个数字的重复项
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }

            // 遍历选择第二个数字
            for (int j = i + 1; j < nums.length; j++) {
                // 检查前两个数字的和是否已经超过目标值
                if (nums[i] + nums[j] > target && nums[i] + nums[j] >= 0) {
                    break;
                }

                // 跳过第二个数字的重复项
                if (j > i + 1 && nums[j] == nums[j - 1]) {
                    continue;
                }

                // 设置两个指针以查找剩下的两个数字
                int left = j + 1;
                int right = nums.length - 1;

                // 使用双指针查找剩下的两个数字
                while (left < right) {
                    // 计算四个数字的和
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];

                    // 如果和小于目标值,移动左指针向右
                    if (sum < target) {
                        left++;
                    }
                    // 如果和大于目标值,移动右指针向左
                    else if (sum > target) {
                        right--;
                    }
                    // 如果和等于目标值,找到一个四元组
                    else {
                        // 将四元组添加到结果列表
                        ret.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));

                        // 跳过第三个数字的重复项
                        while (left < right && nums[left] == nums[left + 1]) {
                            left++;
                        }
                        // 跳过第四个数字的重复项
                        while (left < right && nums[right] == nums[right - 1]) {
                            right--;
                        }
                        // 找到有效的四元组后,移动两个指针
                        left++;
                        right--;
                    }
                }
            }
        }
        // 返回唯一四元组的列表
        return ret;
    }
}

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

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

相关文章

【pytorch】张量求导3

再接上文,补一下作者未补完的矩阵运算的坑。 首先贴一下原作者的图,将其转化为如下代码: import torch import torch.nn as nn import torch.optim as optim# 定义一个简单的两层神经网络 class TwoLayerNet(nn.Module):def __init__(self):super(TwoLayerNet, self).__in…

Markdown 语法详解大全(超级版)(二)

Markdown 语法详解大全(超级版)&#xff08;二&#xff09; Markdown 语法详解大全(超级版)&#xff08;一&#xff09; Markdown 语法详解大全(超级版)&#xff08;二&#xff09; Markdown 语法详解大全(超级版)&#xff08;三&#xff09; &#xff08;歌词节选&#xff09…

Ubuntu 中 Redis ,MySQL 基本使用

1、Redis &#xff08;1&#xff09;启动Redis 服务端客户端命令 服务端 ps aux | grep redis 查看redis服务器进程 sudo kill -9 pid 杀死redis服务器 sudo redis-server /etc/redis/redis.conf 指定加载的配置文件客户端 连接redis&#xff1a; redis-cli运⾏测试命令&am…

C++结构体定义和创建

// // Created by 徐昌真 on 2024/10/5. // #include <iostream> using namespace std;int main() {//结构体的定义 struct 结构体名字 { 结构体成员名字 }struct Book{string name;double price;int value;}java; //java是创建的结构体//创建结构体//这是第一种方式Boo…

目标检测 DAB-DETR(2022)

文章目录 前言Query是什么&#xff0c;Detr收敛速度慢的原因是什么&#xff1f;改进策略位置先验和模型框架设置温度系数 前言 本文认为原始的Detr系列论文中&#xff1a;可学习的object queries仅仅是给model预测box提供了锚点&#xff08;中心点&#xff09;信息&#xff0c…

SpringBoot环境下古典舞交流平台的快速开发

第三章 系统分析 3.1 可行性分析 需要使用大部分精力开发的古典舞在线交流平台为了充分降低开发风险&#xff0c;特意在开发之前进行可行性分析这个验证系统开发是否可行的步骤。本文就会从技术角度&#xff0c;经济角度&#xff0c;还有操作角度等进行综合阐述。 3.1.1技术可行…

Python案例--三数排序

一、引言 在信息爆炸的时代&#xff0c;我们每天都会接触到大量的数据。无论是工作中的报表、学习中的数据集&#xff0c;还是日常生活中的购物清单&#xff0c;数据的有序性对于提高效率和决策质量都至关重要。排序算法作为数据处理的基础工具&#xff0c;其重要性不言而喻。…

日记学习小迪安全27

感觉复制粘贴没有意思&#xff0c;而且还有点浪费时间&#xff0c;主要是学习&#xff0c;不是复制&#xff0c;那就复制别人的吧 第27关就参考这篇文章吧&#xff0c;以下大部分内容都是参考以下文章&#xff08;侵权删除&#xff09; 第27天&#xff1a;WEB攻防-通用漏洞&a…

芯片录-低压差线性稳压器AZ1084D-ADJE1失效记录与原理分析

背景 最近主板坏了&#xff0c;现象是主机不停重启&#xff0c;USB设备LED灯一会儿亮&#xff0c;一会儿灭。经过一些分析和定位&#xff0c;通过测温发现主板上AZ1084D-ADJE1芯片高达91摄氏度&#xff0c;进一步测量该芯片的输出引脚和接地引脚短路&#xff0c;初步推测某些原…

Shell-使用函数

在 Shell 脚本中&#xff0c;函数是由一段代码定义的&#xff0c;可以被重复调用。Shell 函数的定义和调用相对简单&#xff0c;并且它支持参数传递和返回值。错误处理在 Shell 中也非常重要&#xff0c;通常通过检查返回的状态码来判断是否有错误发生。 1.Shell 函数的定义和…

构建高效招聘流程:Spring Boot大学生就业系统

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

28 基于51单片机的两路电压检测(ADC0808)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;通过ADC0808获取两路电压&#xff0c;通过LCD1602显示 二、硬件资源 基于KEIL5编写C代码&#xff0c;PROTEUS8.15进行仿真&#xff0c;全部资源在页尾&#xff0c;提供…

【中间件学习】Git的命令和企业级开发

一、Git命令 1.1 创建Git本地仓库 仓库是进行版本控制的一个文件目录。我们要想对文件进行版本控制&#xff0c;就必须创建出一个仓库出来。创建一个Git本地仓库对应的命令是 git init &#xff0c;注意命令要在文件目录下执行。 hrxlavm-1lzqn7w2w6:~/gitcode$ pwd /home/hr…

Yocto - 使用Yocto开发嵌入式Linux系统_06 掌握Bitbake工具

Grasping the BitBake Tool 在上一章中&#xff0c;我们了解了元数据、元数据集合概念以及 conf/layer.conf 的重要性。在本章中&#xff0c;我们将更深入地研究元数据&#xff0c;了解配方如何相互依赖&#xff0c;并了解 BitBake 如何处理依赖关系。 In the previous chapter…

Python机器视觉:01- 利用列表和切片操作 - 做一个弧线和图片相交的mask区域

前言&#xff1a; Python的列表处理&#xff0c;在机器视觉中经常被用到&#xff0c;这里结合基本的概念机器视觉实践案例&#xff0c;成文如下&#xff1a; 本身将实现一个&#xff0c;弧线的mask填充&#xff1a;这个mask是我的一个天文项目的应用&#xff0c;目的在于将月…

冥想第一千三百零一天(1301)

1.今天上午溪溪和小侄子写作业&#xff0c;我带着桐桐去了惠济区的裕华广场永辉&#xff0c;给家人买了好吃的&#xff0c;下午4点半左右去了妈妈朋友家里摘石榴。 2.感谢父母&#xff0c;感谢朋友&#xff0c;感谢家人&#xff0c;感谢不断进步的自己。

JavaWeb 14.详解TCP协议的三次握手和四次挥手

目录 一、TCP协议与UDP协议 二、TCP协议 1、建立连接&#xff08;三次握手&#xff09; 过程 2、断开连接&#xff08;四次挥手&#xff09; 过程 国庆节快乐&#xff01; 一文详解TCP协议中的三次握手建立连接和四次挥手断开连接 —— 24.10.3 一、TCP协议与UDP协议 tcp协议与…

【可答疑】基于51单片机的智能台灯(含仿真、代码、报告、演示视频等)

✨哈喽大家好&#xff0c;这里是每天一杯冰美式oh&#xff0c;985电子本硕&#xff0c;大厂嵌入式在职0.3年&#xff0c;业余时间做做单片机小项目&#xff0c;有需要也可以提供就业指导&#xff08;免费&#xff09;~ &#x1f431;‍&#x1f409;这是51单片机毕业设计100篇…

MATLAB中minres函数用法

目录 语法 说明 示例 线性系统的迭代解 使用指定了预条件子的 minres 提供初始估计值 使用函数句柄代替数值矩阵 minres函数的功能是求解线性系统 - 最小残差法。 语法 x minres(A,b) x minres(A,b,tol) x minres(A,b,tol,maxit) x minres(A,b,tol,maxit,M) x mi…

CPU性能篇-平均负载-Day 01

1. 平均负载 1.1 什么是平均负载 平均负载是指单位时间内&#xff0c;系统处于可运行状态和不可中断状态的平均进程数&#xff0c;也就是平均活跃进程数&#xff0c;它和 CPU 使用率并没有直接关系。 1.1.1 什么是可运行状态 指正在使用 CPU 或者正在等待 CPU 的进程&#xff…