LeetCode热题100 (Java)(1)哈希

本章包括的题目有:

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

49. 字母异位词分组 - 力扣(LeetCode)

128. 最长连续序列 - 力扣(LeetCode)

1.两数之和

思路解析:

由于要在一堆无序的数中找到两个数的和为target,只需先拿到一个值,然后匹配有没有另一个即可。由于需要返回下标,我们可以用哈希表来表示一个元素的值和下标。

遍历数组 nums,对于当前元素 nums[i]。检查哈希表中是否已存在一个值与之和为target。若存在,说明之前遍历过的某个数与当前数之和等于目标值,直接返回这两个数的索引。若不存在,将当前元素 (nums[i], i) 存入哈希表,供后续元素匹配。题目保证有且仅有一个有效解,因此循环内一定会返回结果。

代码实现:

java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int complement = target - nums[i];
            if (map.containsKey(complement)) {
                return new int[]{map.get(complement), i};
            }
            map.put(nums[i], i);
        }
        return new int[0]; // 根据题目约定,此处不会执行到
    }
}

时间复杂度O(n)

空间复杂度O(n)

2.字母的异位词分组

思路解析:

由于要对一堆字符串按照字母异位词分组,只需将每个字符串的字符排序后作为唯一标识,相同标识的字符串属于同一组。由于需要返回分组结果,我们可以用哈希表来表示一个排序后的字符串(键)和对应的原字符串列表(值)。

遍历字符串数组 strs,对于当前字符串 strs[i]:将其转换为字符数组并排序,再转换回字符串作为键 key。检查哈希表中是否已存在该键:若存在,将当前字符串添加到对应的列表中;若不存在,则先创建一个新列表再添加。最后,哈希表中所有的 value 集合即为分组结果,直接转换为 ArrayList 返回。题目不要求保持顺序,因此无需额外处理。

代码实现:

java 复制代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        int n = strs.length;
        Map<String, List<String>> map = new HashMap<>();
        for(int i = 0;i < n;i ++){
            char[] chars = strs[i].toCharArray();
            Arrays.sort(chars);
            String key = new String(chars);
            map.computeIfAbsent(key,k -> new ArrayList<>()).add(strs[i]);
        }
        return new ArrayList<>(map.values());
    }
}

computeIfAbsent方法会先查找是否有key,若有则获得其value(顺序表),若没有就添加key到map中,并通过后面的计算函数得到一个value存入map中作为新添加的key的值(此处为一个空顺序表),再通过add方法将对应的字符串添加其中。

map.values()的返回值是一个Collection,而不是List,所以不可以直接返回,而ArrayList的构造器可以接受Collection,所以可以构造成ArrayList再返回。

时间复杂度O( n * L log L ) //n为字符串数组的长度,L为字符串平均长度

空间复杂度O( n * L)

3.最长连续序列

思路解析:

由于要在无序数组中找到最长连续序列的长度,最朴素的想法是先排序,然后遍历。但是要求时间复杂度 O(n),因此不能做排序处理,我们可以用一个哈希集合来去重和匹配相邻的数。

我们只需将所有数字存入哈希集合,然后遍历集合中的每个数字。对于当前数字 n,若它的前驱 n-1 不存在于集合中,则说明 n 是一个连续序列的起点。从该起点开始,不断检查集合中是否存在 n+1、n+2......并累加计数。这样每个元素最多被访问两次(一次作为起点向后扩展,一次作为非起点被跳过),总体线性。最终返回最大计数即可。

代码实现:

java 复制代码
class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for(int num : nums){
            set.add(num);
        }
        int result = 0;
        for (Integer n : set) {
            int mid = 1; //进循环说明当前数一定存在于原数组,所以从1开始记录结果
            if(set.contains(n - 1)){
                continue;
            }
            while(set.contains(n + 1)){
                mid ++;
                n ++;
            }
            if(mid > result) result = mid;
        }
        return result;
    }
}

时间复杂度O(n)

空间复杂度O(n)

下一章:

LeetCode热题100(Java)(2)双指针-CSDN博客

相关推荐
技术小黑10 分钟前
CNN算法实战系列03 | DenseNet121算法实战与解析
pytorch·深度学习·算法·cnn
wearegogog12336 分钟前
三电平SVPWM逆变器仿真指南
单片机·算法
笨笨饿1 小时前
74_SysTick滴答定时器中断
c语言·开发语言·人工智能·单片机·嵌入式硬件·算法·学习方法
pkowner2 小时前
若依分页问题及解决方法
java·前端·算法
呃呃本2 小时前
算法题(栈)
算法
通信小呆呆2 小时前
基于 ADMM-MFOCUSS 的捷变频雷达扩展目标稀疏重构原理
算法·重构·信息与通信·信号处理·雷达
橙淮2 小时前
Java数组与链表:特性对比与应用场景
数据结构·算法
炽烈小老头2 小时前
【每天学习一点算法 2026/05/15】被围绕的区域
学习·算法·深度优先
芜湖xin2 小时前
【题解-洛谷】P1012 [NOIP 1998 提高组] 拼数
算法·贪心
xiaoxiaoxiaolll3 小时前
金属结构疲劳寿命预测与健康监测技术
人工智能·算法·机器学习