算法练习01——哈希部分双指针

目录

  • 1. 两数之和(*)
  • 242. 有效的字母异位词(easy)
  • 49. 字母异位词分组(*)
  • 349. 两个数组的交集
  • 202. 快乐数(1.使用Set存哈希,2.快慢指针)
  • 454. 四数相加 II
  • 383. 赎金信
  • 15. 三数之和*(双指针)
  • 18. 四数之和*(双指针)
  • 128. 最长连续序列

1. 两数之和(*)

https://leetcode.cn/problems/two-sum/
在这里插入图片描述

使用map存储遍历过的数组中的值,每遍历到一个元素,就去map集合中查找有没有值为(target-num[i])的元素。
map的key存储数组元素的值,value存储数组元素的下标。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer>map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(target-nums[i])){
                return new int[]{i,map.get(target-nums[i])};
            }
            map.put(nums[i],i);
        }
        return null;
    }
}

242. 有效的字母异位词(easy)

https://leetcode.cn/problems/group-anagrams/

class Solution {
    public boolean isAnagram(String s, String t) {
        int hash[]=new int[26];
        for(int i=0;i<s.length();i++){
            hash[s.charAt(i)-'a']++;
        }
        for(int i=0;i<t.length();i++){
            hash[t.charAt(i)-'a']--;
        }
        for(int i=0;i<26;i++){
            if(hash[i]!=0){
                return false;
            }
        }
        return true;
    }
}

49. 字母异位词分组(*)

https://leetcode.cn/problems/group-anagrams/

由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键。

//方法一:排序
 class Solution {
   public List<List<String>> groupAnagrams(String[] strs) {
    // 创建一个哈希映射,键是排序后的字符串,值是所有对应的异位词
    Map<String, List<String>> map = new HashMap<String, List<String>>();
    
    // 遍历输入的字符串数组
    for (String str : strs) {
        // 将当前字符串转换为字符数组
        char[] array = str.toCharArray();
        // 对字符数组进行排序
        Arrays.sort(array);
        // 将排序后的字符数组转换回字符串,作为哈希映射的键
        String key = new String(array);
        // 从哈希映射中获取键对应的异位词列表,如果不存在则返回一个新的列表
        List<String> list = map.getOrDefault(key, new ArrayList<String>());
        // 将当前字符串添加到异位词列表中
        list.add(str);
        // 将异位词列表放回哈希映射中
        map.put(key, list);
    }
    // 将哈希映射中的所有值(即所有的异位词列表)转换为一个列表返回
    return new ArrayList<List<String>>(map.values());
}

方法一:计数: `
由于互为字母异位词的两个字符串包含的字母相同,因此两个字符串中的相同字母出现的次数一定是相同的,故可以将每个字母出现的次数使用字符串表示,作为哈希表的键。

由于字符串只包含小写字母,因此对于每个字符串,可以使用长度为 262626 的数组记录每个字母出现的次数。需要注意的是,在使用数组作为哈希表的键时,不同语言的支持程度不同,因此不同语言的实现方式也不同。

  class Solution {
  public List<List<String>> groupAnagrams(String[] strs) {
    // 创建一个哈希映射,键是字符计数字符串,值是所有对应的异位词
    Map<String, List<String>> map = new HashMap<String, List<String>>();
    
    // 遍历输入的字符串数组
    for (String str : strs) {
        // 创建一个长度为26的数组,用于记录每个字符的出现次数
        int[] counts = new int[26];
        int length = str.length();
        // 遍历当前字符串,更新字符计数数组
        for (int i = 0; i < length; i++) {
            counts[str.charAt(i) - 'a']++;
        }
        // 创建一个字符串缓冲区,用于构建字符计数字符串
        StringBuffer sb = new StringBuffer();
        // 遍历字符计数数组,将每个出现次数大于0的字符和出现次数按顺序拼接成字符串
        for (int i = 0; i < 26; i++) {
            if (counts[i] != 0) {
                sb.append((char) ('a' + i));
                sb.append(counts[i]);
            }
        }
        // 将字符计数字符串作为哈希映射的键
        String key = sb.toString();
        // 从哈希映射中获取键对应的异位词列表,如果不存在则返回一个新的列表
        List<String> list = map.getOrDefault(key, new ArrayList<String>());
        // 将当前字符串添加到异位词列表中
        list.add(str);
        // 将异位词列表放回哈希映射中
        map.put(key, list);
    }
    // 将哈希映射中的所有值(即所有的异位词列表)转换为一个列表返回
    return new ArrayList<List<String>>(map.values());
}

349. 两个数组的交集

https://leetcode.cn/problems/intersection-of-two-arrays/

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> resSet=new HashSet<>();
        Set<Integer> set=new HashSet<>();
        for(int i:nums1){
            set.add(i);
        }
        for(int i:nums2){
            if(set.contains(i)){
                resSet.add(i);
            }
        }
        int j=0;
        int []arr=new int[resSet.size()];
        for(int i:resSet){
            arr[j++]=i;
        }
        return arr;
    }
}

202. 快乐数(1.使用Set存哈希,2.快慢指针)

https://leetcode.cn/problems/happy-number/

class Solution {
    public boolean isHappy(int n) {
        //方法一:使用SetHash检测循环
        Set<Integer> set=new HashSet<>();
        while(n!=1 && !set.contains(n)){
            set.add(n);
            n=getNextNumber(n);
        }
        return n==1;

        //方法二:使用快慢指针检测循环
        // int fast=getNextNumber(n);
        // int slow=n;
        // while(fast!=1 && fast!=slow){
        //     slow=getNextNumber(slow);
        //     fast=getNextNumber(getNextNumber(fast));
        // }
        // return fast==1;
    }
    //将n替换为它每个位置上的数字的平方和。
    private int getNextNumber(int n) {
        int res = 0;
        while (n > 0) {
            int temp = n % 10;
            res += temp * temp;
            n = n / 10;
        }
        return res;
    }
}

454. 四数相加 II

https://leetcode.cn/problems/4sum-ii/

我们可以将四个数组分成两部分,A和 B 为一组,C 和 D 为另外一组。
对于 A 和 B,我们使用二重循环对它们进行遍历,得到所有 A[i]+B[j] 的值并存入哈希映射中。对于哈希映射中的每个键值对,每个键表示一种 A[i]+B[j],对应的值为 A[i]+B[j] 出现的次数。
对于 C 和 D,我们同样使用二重循环对它们进行遍历。当遍历到 C[k]+D[l]时,如果 −( C[k]+D[l] )出现在哈希映射中,那么将 −(C[k]+D[l]) 对应的值累加进答案中。
最终即可得到满足 A[i]+B[j]+C[k]+D[l]=0 的四元组数目。

class Solution {
    public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        int res = 0;
        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);
            }
        }
        //统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
        for (int i : nums3) {
            for (int j : nums4) {
                res += map.getOrDefault(0 - i - j, 0);
            }
        }
        return res;
    }
}

383. 赎金信

https://leetcode.cn/problems/ransom-note/

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        if(ransomNote.length() > magazine.length()){
            return false;
        }
        int []hash=new int[26];
        for(char ch : magazine.toCharArray()){
            hash[ch-'a']++;
        }
        for(char ch : ransomNote.toCharArray()){
            hash[ch-'a']--;
        }
        for(int i=0;i<26;i++){
            if(hash[i]<0){
                return false;
            }
        }
        return true;
    }
}

15. 三数之和*(双指针)

https://leetcode.cn/problems/3sum/

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res=new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0){
                return res;
            }
            if(i>0 && nums[i]==nums[i-1]){ //去重
                continue;
            }
            int left=i+1;
            int right=nums.length-1;
            while(left<right){
                if(nums[i]+nums[left]+nums[right]>0){
                    right--;
                }else if(nums[i]+nums[left]+nums[right]<0){
                    left++;
                }else{
                    List<Integer> list=new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[left]);
                    list.add(nums[right]);
                    res.add(list);
                    while(left<right && nums[right]==nums[right-1]){
                        right--;
                    }
                    while(left<right && nums[left]==nums[left+1]){
                        left++;
                    }
                    right--;
                    left++;
                }
            }
        }
        return res;
    }
}

18. 四数之和*(双指针)

https://leetcode.cn/problems/4sum/

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> res=new ArrayList<>();
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0 && nums[i]>target){//剪枝
                return res;
            }
            if(i>0 && nums[i]==nums[i-1]){ //去重
                continue;
            }
            for(int j=i+1;j<nums.length;j++){
                if(j>i+1 && nums[j]==nums[j-1]){ //去重
                    continue;
                }
                int left=j+1;
                int right=nums.length-1;
                while(left<right){
                    if(nums[i]+nums[j]+nums[left]+nums[right]>target){
                        right--;
                    }else if(nums[i]+nums[j]+nums[left]+nums[right]<target){
                        left++;
                    }else{
                        List<Integer> list=new ArrayList<>();
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[left]);
                        list.add(nums[right]);
                        res.add(list);
                        while(left<right && nums[right]==nums[right-1]){
                            right--;
                        }
                        while(left<right && nums[left]==nums[left+1]){
                            left++;
                        }
                        right--;
                        left++;
                    }
                }
            }
        }
        return res;
    }
}

128. 最长连续序列

https://leetcode.cn/problems/longest-consecutive-sequence/

class Solution {
    public int longestConsecutive(int[] nums) {
        int res = 0;    // 记录最长连续序列的长度
        Set<Integer> numSet = new HashSet<>();  // 记录所有的数值
        for(int num: nums){
            numSet.add(num);    // 将数组中的值加入哈希表中
        }
        int seqLen;     // 连续序列的长度
        for(int num: numSet){
            // 如果当前的数是一个连续序列的起点,统计这个连续序列的长度
            if(!numSet.contains(num - 1)){
                seqLen = 1;
                while(numSet.contains(++num))seqLen++;  // 不断查找连续序列,直到num的下一个数不存在于数组中
                res = Math.max(res, seqLen);    // 更新最长连续序列长度
            }
        }
        return res;
    }
}

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

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

相关文章

边缘计算网关在智能制造中有哪些应用?-天拓四方

在智能制造和工业生产环境中&#xff0c;数据已经成为新的生产要素&#xff0c;工业生产对实时性、灵活性和智能化也提出了更高的要求。而在这个过程中&#xff0c;边缘计算网关发挥着不可或缺的作用。它作为设备层与网络层之间的关键桥梁&#xff0c;确保了数据的实时、高效处…

STM32F407移植OpenHarmony笔记6

继上一篇笔记&#xff0c;编译好STM32的裸机程序&#xff0c;能点亮LED灯了。 下一步就是启动liteos_m内核了。 不过为了更好的调试代码&#xff0c;需要先把printf重定向到串口&#xff0c;基于gcc的printf重定向和Keil不一样。 直接新建printf.c&#xff0c;在里面重写printf…

基于 NOVATEK NT98530 Multiview Stitching 应用解决方案

感测技术近来于影像监控系统应用有了进一步的发展&#xff0c;多镜头的应用也与日俱增&#xff0c;如 AI 视觉感测会议相机&#xff0c;能满足远端多人聚会、远距教育训练的多元需求等&#xff0c;相关应用层面广泛涵盖了在生活中所面对的各种场景&#xff0c;带动更加可观的潜…

【安装指南】nodejs下载、安装与配置详细教程

目录 &#x1f33c;一、概述 &#x1f340;二、下载node.js &#x1f337;三、安装node.js &#x1f341;四、配置node.js &#x1f33c;一、概述 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建可扩展的网络应用程序。Node.js 使用事件驱动、…

各品牌主板快速启动热键对照表及CMOS进入方法

各品牌主板快速启动热键对照表 主板品牌 启动按键 笔记本品牌 启动按键 主机品牌 启动按键 华硕主板 F8 联想笔记本 F12 联想台式机 F12 技嘉主板 F12 宏碁笔记本 F12 惠普台式机 F12 微星主板 F11 华硕笔记本 ESC 宏碁台式机 F12 梅捷主板 F9 惠普笔…

机器学习数学基础

机器学习基础 1、标量、向量、矩阵、张量2、概率函数、概率分布、概率密度、分布函数3、向量的线性相关性4、最大似然估计5、正态分布(高斯分布)6、向量的外积(叉积)7、向量的内积(点积)8、超平面(H)1、标量、向量、矩阵、张量 标量、向量、矩阵和张量是线性代数中不同…

Java基础学习:System类和Static方法的实际使用

一、System类 1.在程序开发中&#xff0c;我们需要对这个运行的结果进行检验跟我们预判的结果是否一致&#xff0c;就会用到打印结果在控制台中显示出来使用到了System类。System类定义了一些和系统相关的属性和方法&#xff0c;它的属性和方法都是属于静态的&#xff0c;想使用…

win11安装wsl作为linux子系统并当作服务器

wsl安装 打开控制面板&#xff0c;找到启用或关闭windows功能 开启windows虚拟机监控平台和适用于Linux的Windows子系统&#xff0c;重启电脑。 打开microsoft store搜索ubuntu&#xff0c;找到合适的版本下载安装 输入wsl -l如下所示&#xff0c;即为安装成功。 安装过程比较…

怎么进行视频压缩大小?常见的4种压缩方法

在当今数字化的时代&#xff0c;我们经常处理大量的视频文件&#xff0c;无论是用于社交媒体分享、视频制作还是存储在我们的设备中。然而&#xff0c;随着视频质量的提升和分辨率的增加&#xff0c;视频文件的大小也相应地变得更加庞大&#xff0c;给存储、分享和传输带来了一…

HTTPS之使用acme.sh申请免费ssl证书

1、步骤一&#xff1a;安装 acme.sh acme.sh 是一个集成了 ACME 客户端协议的 Bash 脚本 a、安装命令 curl https://get.acme.sh | sh -s emailusernameexample.com 或者 git clone --depth 1 https://github.com/acmesh-official/acme.sh.git cd acme.sh ./acme.sh --ins…

循环系统的血流方向 Circulatory System‘s Pathway of Blood Through the Heart

循环系统的血流方向 目录 循环系统的血流方向前置知识&#xff1a;心脏腔室和阀门&#xff1a;血液路线&#xff1a;心脏瓣膜病 循环系统是由心脏、血管和血液组成的复杂系统&#xff0c;负责输送氧气、营养和其他物质到身体的各个部位&#xff0c;并将代谢产物带回肺和肾脏等器…

【力扣经典面试题】189. 轮转数组

题目描述&#xff1a; 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 …

SIT1145AQ带选择性唤醒及故障保护的低功耗 CAN FD 总线收发器

特点 符合 ISO 11898-2:2016 和 SAE J2284-1 至 SAE J2284-5 标准 ➢ AEC-Q100 认证 ➢ 拥有低功耗休眠模式以及待机模式 ➢ 支持标准 CAN 唤醒帧的远程唤醒&#xff0c;兼容 ISO 11898- 2:2016 标准的选择性唤醒帧远程唤醒 ➢ 唤醒源诊断识别功能 ➢ 总…

二月外贸新规,外贸人请查收

政策导读&#xff1a; 1.新版《稳外贸稳外资税收政策指引》发布&#xff1b; 2.商务部公布2024年进出口许可证发证机构名录&#xff1b; 3.2月9日起中国和新加坡互免签证&#xff1b; 4.进出口低含量三乙醇胺混合物产品无需办理两用物项许可证&#xff1b; 5.USB-C成为欧盟…

通过与chatGPT交流实现零样本事件抽取

1、写作动机&#xff1a; 近来的大规模语言模型&#xff08;例如Chat GPT&#xff09;在零样本设置下取得了很好的表现&#xff0c;这启发作者探索基于提示的方法来解决零样本IE任务。 2、主要贡献&#xff1a; 提出了基于chatgpt的多阶段的信息抽取方法&#xff1a;在第一阶…

企业网络基础架构监控工具

IT 基础架构已成为提供基本业务服务的基石&#xff0c;无论是内部管理操作还是为客户托管的应用程序服务&#xff0c;监控 IT 基础设施至关重要&#xff0c;并且已经建立起来&#xff0c;SMB IT 基础架构需要简单的网络监控工具来监控性能和报告问题。通常&#xff0c;几个 IT …

写个Android事件分发实际用例(持续更新)

一&#xff0c;概述 感兴趣的读者&#xff0c;如果对Android事件分发还有不了解的地方&#xff0c;可以阅读笔者写的文章再谈android事件分发机制。 本文的主要目的&#xff0c;是结合前文所分享事件分发相关原理&#xff0c;在实际案例中使用。 二&#xff0c;Recycler嵌套…

SourceTree 不显示新添加文件

最近遇到了在项目中新添加了文件&#xff0c;但是在提交的时候SourceTree 中“未暂存区域”却不显示文件。如果你也有类似的问题&#xff0c;不防来看看吧。 我可能不知道什么时候动了下面的配置&#xff1a; 配置选择为“待定”&#xff0c;新增的未提交文件就显示出来了&…

Pycharm连接云算力远程服务器(AutoDL)训练深度学习模型全过程

前言&#xff1a;在上一篇windows搭建深度学习环境中&#xff0c;我试图使用笔记本联想小新air14的mx350显卡训练一个图像检测的深度学习模型&#xff0c;但是训练时长大概需要几天时间远超我的预期&#xff0c;所以我便选择租用GPU进行训练&#xff0c;在对多家平台对比后找到…

在Arduino给自己的SSD1306 OLED显示定制Logo或者图片

我在使用Arduino上的SSD1306显示屏时&#xff0c;基本都用使用Adafruit的SSD1306库&#xff0c;但是Adafruit的开机logo实在没特色&#xff08;如下图&#xff09;&#xff0c;如果在开机时&#xff0c;让自己的项目上显示自己的定制logo&#xff0c;甚至是照片&#xff08;如果…