Leetcode热题100中的:哈希专题

前言

  • 只用Java。

1.两数之和

关键信息一句话总结:

查找补数是否出现过 -> 哈希表

  • 方法1:双重for循环。
java 复制代码
import java.util.Arrays;

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] ans = new int[] { 0, 0 };
        for (int i = 0; i < nums.length; i++) {
            int need = target - nums[i];
            for ( int j = 0 ; j < i; j ++ ){
                if ( need == nums[j] ){
                    ans[0] = j;
                    ans[1] = i;
                }
            }
        }
        return ans;
    }

}
  • 方法2:哈希表。
  • 难点1:在于你能不能想到哈希表,只看题目,不要看算法标签,为什么用哈希表?
  • 分析1:哈希表用于快速通过键找到值,key -> value。那么关键就在于定义合适的key和value。好的,联想到实习的时候运用的哈希关联,用一个HashMap记录键值对,然后变多层循环为少层循环。
  • 难点2:java如何实现哈希表
  • 分析2:
java 复制代码
Map<T, G> hashMap = new HashMap<>();
G item = hashMap.get(key);
hashMap.put(key, value);
hashMap.remove(key);
hashMap.remove(key, value);
boolean bool = hashMap.containsKey(key);
boolean bool = hashMap.containsValue(value);
hashMap.clear();
// 遍历键值对
hashMap.forEach((k, v) -> {
	// doanything
});
// 遍历值
for(G each : hashMap.values()){
	// doanything
}
// 遍历键
for(T each : hashMap.keySet()){
	// doanything
}
  • 反思:这道题是数值 -> 索引号,把target - 数字的值作为了key,索引号为value,在一次遍历的时候,因为 a + b = target, 所以target - a = b,遍历到a时判断对应的b存不存在就可以了
java 复制代码
import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

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

}

49.字母异位词分组

关键信息一句话总结:

等价类分组问题 → 构造标准化 key → HashMap

  • 分析1:将顺序不同的字母组成的单词归类到一起,很显然,它们在排序后的值一摸一样,所以我们要进行排序操作,然后把排序后值一样的单词归类到一起,我们使用哈希表来模拟这种操作,key为排序后的单词,value为收集的结果,如果一个单词排序后与key一致,就加入这个value,如果key不存在,就创建一个这个单词的key
java 复制代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 重点是谁为键 排序后的字符串可以作为它们的共同键
       Map<String, List<String>> map = new HashMap<>();
       for(String str : strs) {
            char[] array = str.toCharArray();
            Arrays.sort(array);
            String key = new String(array);
            List<String> val = map.get(key);
            if(val == null) {
                val = new ArrayList<>();
            } 
            val.add(str);
            // 要重新put回map 并不是修改完了就行了 因为java是值传递 不会修改原值
            map.put(key, val);
       }
       // 创建List的方法 把map.values()转化成List即可
       return new ArrayList<List<String>>(map.values());
    }
}
  • 反思:我没有想明白设为key合适,谁为value合适,我应该下次使用哈希的时候要想明白这个事情,何为key,何为value

128.最长连续序列

关键信息一句话总结:

利用 HashSet 快速查找 + 只从序列起点扩展 → 去重后的连续区间统计问题

  • 分析:我们需要在一个乱序的数组里面找出数字连续的最长序列,且只能用一次扫描,观察到例子中有重复的元素只算一次,那么我们要先将所有数据进行去重,然后在去重后的数字里面遍历每一个数,遍历到当前数字时,判断去重后的数字里面是否有只比当前数字大1的数字,如果有,那么一直延申下去,如果没有了,不再延申,记录此时的长度与最大长度比较,长度重新计算,直到遍历完所有的元素
java 复制代码
class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> set = new HashSet<>();
        // 1.先放在集合里避免二次扫描时消耗时间复杂度
        for(int each : nums) {
            set.add(each);
        }
        int max = 0;
        // 2.再从集合里面找
        for(int num : set) {
            // 这个数不存在比他小1的数 说明它就是起点
            if(!set.contains(num - 1)) {
                int leng = 1;
                int start = num;
                // 3.一直延申出去
                while(set.contains(start + 1)) {
                    leng++;
                    start++;
                }
                max = Math.max(leng, max);
            }
        }
        return max;
    }
}
  • 反思:要善于观察,一步一步抽丝剥茧,而不是一上来就用哈希,这道题其实没用哈希,用了集合去重和简单查找
相关推荐
wefg11 小时前
【算法】倍增思想(快速幂)
数据结构·c++·算法
Zik----2 小时前
Leetcode24 —— 两两交换链表中的节点(迭代法)
数据结构·算法·链表
SmartBrain2 小时前
通俗讲解:Agent Skill和智能体的技术概念
人工智能·算法
爱喝热水的呀哈喽2 小时前
副产品技法
算法
!停2 小时前
数据结构二叉树—链式结构(下)
数据结构·算法
逆境不可逃2 小时前
LeetCode 热题 100 之 41.缺失的第一个正数
算法·leetcode·职场和发展
码上发达3 小时前
状态压缩搜索解法(DFS + Dominance)
算法
颜酱3 小时前
差分数组:高效处理数组区间批量更新的核心技巧
javascript·后端·算法
yyy(十一月限定版)3 小时前
图论——最小生成树Kruskal算法
算法·图论