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

news2024/11/24 4:52:49

目录

  • 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;
    }
}

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

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

相关文章

Acwing---797.差分

差分 1.题目2.基本思想3.代码实现 1.题目 输入一个长度为 n n n 的整数序列。 接下来输入 m m m 个操作&#xff0c;每个操作包含三个整数 l , r , c l,r,c l,r,c&#xff0c;表示将序列中 [ l , r ] [l,r] [l,r] 之间的每个数加上 c c c。 请你输出进行完所有操作后的…

2024新利好!一文读懂Shopee 3PF PFF一店多运模式

2023年年底&#xff0c;Shopee平台又有大动作&#xff01;正式上线了3PF PFF一店多运模式&#xff0c;已完成库存管理模式升级的三方仓卖家&#xff0c;即可开启一店多运新模式。 图源&#xff1a;Shopee 一、3PF PFF模式优势解析 三方仓一店多运&#xff08;3PF PFF&#xf…

什么可以用手机蓝牙控制LED???#串口通信【下】

什么可以用手机蓝牙控制LED&#xff1f;&#xff1f;&#xff1f;#串口通信【下】 前言预备知识1.小白玩串口控制的ASSII避坑1.1问题引入1.2解决问题 2.串口支持单词型指令控制2.1实现串口支持单词型指令控制的核心思路2.2利用字符数组来承接单词型指令2.3利用strstr函数来查找…

【Java程序设计】【C00202】基于(JavaWeb+SSM)的信访管理系统(论文+PPT)

基于&#xff08;JavaWebSSM&#xff09;的信访管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的信访管理系统 本系统分为管理员、信访人员和工作人员3个功能模块。 管理员&#xff1a;管理员登录进入信访管理系…

从0到1入门C++编程——06 类和对象之多态、文件操作

文章目录 多态1.多态基本概念2.多态案例——计算器3.纯虚函数和抽象类4.多态案例——制作饮品5.虚析构和纯虚析构6.多态案例——电脑组装 文件操作1.文本文件--写文件2.文本文件--读文件3.二进制文件--写文件4.二进制文件--读文件 多态 1.多态基本概念 多态是C面向对象的三大…

RHEL 9上创建本地Yum/DNF存储库

1.挂载RHEL9 ISO文件或DVD 我们假设RHEL 9 iso文件已经复制到系统中。运行以下mount 命令将 ISO文件挂载到/var/repo文件夹。 $ sudo mkdir /var/repo $ sudo mount -o loop rhel-baseos-9.0-x86_64-dvd.iso /var/repo/ 如果是 DVD,请运行 $ sudo mount /dev/sr0 /var/repo/…

系统架构设计师-22年-下午答案

系统架构设计师-22年-下午答案 更多软考知识请访问 https://ruankao.blog.csdn.net/ 试题一必答&#xff0c;二、三、四、五题中任选两题作答 试题一 (25分) 说明 某电子商务公司拟升级其会员与促销管理系统&#xff0c;向用户提供个性化服务&#xff0c;提高用户的粘性。…

代码随想录 Leetcode669. 修剪二叉搜索树

题目&#xff1a; 代码(首刷看解析 2024年1月31日&#xff09;&#xff1a; class Solution { public:TreeNode* trimBST(TreeNode* root, int low, int high) {if (!root) return root;if (root->val < low) {TreeNode* node trimBST(root->right,low,high);return…

【Linux】yum与vim命令详解

&#x1f497;个人主页&#x1f497; ⭐个人专栏——Linux学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读1. yum命令1.1 基本使用1.2 注意事项1.3 lrzsz软件包示例 2. vim命令2.1 vim的基本概念2.2 vim配置2.3 vim的基本操作2.3…

远程电脑解决突然无法的复制粘贴问题

方法一 - 重新启动RDP剪贴板 结束掉剪切板服务 创建新任务rdplclip.exe任务 重新复制粘贴&#xff0c;即可解决 方法二&#xff1a; 重新启动 Windos 资源管理器 方法三&#xff1a;设置远程桌面连接的本地资源配置&#xff0c;勾选剪切板服务&#xff0c;并在详细信息中勾选…

如何用 python +ddt+excel 实现接口自动化测试

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 “ 接口自动化测试是指通过编写代码或使用工具&#xff0c;模拟…

计算机网络——网络层(3)

计算机网络——网络层&#xff08;3&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU)1 网络层——控制平面因特网中自治系统内部的路由选择总括考虑因素总结 ISP之间的路由选择&#xff1a;BGP考虑因素总结 SDN控制层面重要组件和功能总结 ICMP主要功能和特点…

Mysql单行函数练习

数据表 链接&#xff1a;https://pan.baidu.com/s/1dPitBSxLznogqsbfwmih2Q 提取码&#xff1a;b0rp --来自百度网盘超级会员V5的分享 单行函数练习 单行函数(一行数据返回一个结果) #1.显示系统时间(注:日期时间) #2.查询员工工号,姓名,工资以及提高百分之20后的结果(new…

消费观念升级,品牌又有哪些新的营销玩法?

一方面在传统消费升级的背景下&#xff0c;国民的消费预期不断改善&#xff0c;购买力持续增强&#xff0c;另一方面&#xff0c;随着Z时代成为消费时代的主力军&#xff0c;他们的需求推动了消费行业向个性化、细分化、多样化的方向发展。那在这一消费环境下&#xff0c;品牌又…

深入解析企业培训教育系统开发:源码探秘与技术实践

当下&#xff0c;为了提高员工的技能水平、促进团队的协同合作&#xff0c;企业培训教育系统成为了一个不可或缺的组成部分。本篇文章&#xff0c;小编将为大家讲述企业培训教育系统的开发&#xff0c;揭示其源码背后的奥秘以及相关的技术实践。 一、概述 企业培训教育系统通常…

时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)

目录 引言 LSTM的预测效果图 LSTM机制 了解LSTM的结构 忘记门 输入门 输出门 LSTM的变体 只有忘记门的LSTM单元 独立循环(IndRNN)单元 双向RNN结构(LSTM) 运行代码 代码讲解 引言 LSTM&#xff08;Long Short-Term Memory&#xff09;是一种常用的循环神经网络&a…

本地搭建Plex私人影音网站并结合内网穿透实现公网远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

网址的静态码和活码怎么做?学会在线制作更快捷

现在获取信息大多都是在手机上搜索的&#xff0c;所以将现在很多推广信息的链接都会选择生成二维码之后&#xff0c;通过扫码在手机上获取传递的信息&#xff0c;那么如何将网址制作二维码使用呢&#xff1f;其实方法很简单&#xff0c;接着网址二维码生成器就可以轻松完成在线…

小程序定制开发前,应该考虑些什么?

引言 在移动互联网时代&#xff0c;小程序已经成为许多企业和个人推广业务、提供服务的理想平台。然而&#xff0c;在进行小程序定制开发之前&#xff0c;开发者和业务方需要细致入微地考虑一系列关键因素&#xff0c;以确保最终的小程序既能满足用户需求&#xff0c;又能够顺…

【附安装包】Java/JDK介绍、下载、安装、配置与使用(保姆级教程)

目录 一、概述 1、Java历史 2、Java介绍&#xff08;JDK、JRE、JVM&#xff09; 3、Java运行机制 4、Java跨平台性 5、JDK版本选择 二、下载安装 1、JDK下载 2、JDK安装 三、配置环境变量 四、测试与使用 1、测试 2、使用 一、概述 1、Java历史 Java语言诞生于SU…