LeetCode_hot100_hash

1.哈希

两数之和

题目:

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

示例 1:

复制代码
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

复制代码
输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

复制代码
输入:nums = [3,3], target = 6
输出:[0,1]
java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] nums1 =new int[2];
        for(int i=0;i<nums.length;i++){
            for(int j=i+1;j<nums.length;j++){
                if(nums[i]+nums[j]==target){
                    nums1[0]=i;
                    nums1[1]=j;
                }
            }
        }
        return nums1;
    }
}

当前:枚举

建议:哈希表/数组

核心考察:利用哈希表空间换时间,快速查找互补数

java 复制代码
class Solution {
    public int[] twoSum(int[] nums, int target) {
       // key:数组中的数字,value:数字对应的下标
        Map<Integer, Integer> map = new HashMap<>();
        
        for (int i = 0; i < nums.length; i++) {
            int curNum = nums[i];
            // 算出需要匹配的另一半数字
            int need = target - curNum;
            
            // 哈希表中存在另一半,说明找到答案
            if (map.containsKey(need)) {
                // map.get(need) 是之前存的下标,i是当前下标
                return new int[]{map.get(need), i};
            }
            
            // 没找到就把当前数字和下标存入map,供后面遍历匹配
            map.put(curNum, i);
        }
        return new int[]{};
    }
}

字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

示例 1:

输入: strs = "eat", "tea", "tan", "ate", "nat", "bat"

输出:\["bat","nat","tan","ate","eat","tea"]

解释:

  • 在 strs 中没有字符串可以通过重新排列来形成 "bat"
  • 字符串 "nat""tan" 是字母异位词,因为它们可以重新排列以形成彼此。
  • 字符串 "ate""eat""tea" 是字母异位词,因为它们可以重新排列以形成彼此。

示例 2:

输入: strs = ""

输出:\[""]

示例 3:

输入: strs = "a"

输出:\["a"]

java 复制代码
class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 1. 创建哈希表:key=排序后的字符串,value=同组异位词列表
        Map<String, List<String>> map = new HashMap<>();

        // 2. 遍历每一个单词
        for (String str : strs) {
            // 2.1 将字符串转为字符数组,排序
            char[] charArr = str.toCharArray();
            Arrays.sort(charArr);
            // 排序后转回字符串,作为分组唯一key
            String sortKey = new String(charArr);

            // 2.2 如果map没有这个key,新建空列表
            if (!map.containsKey(sortKey)) {
                map.put(sortKey, new ArrayList<>());
            }
            // 2.3 取出列表,把当前单词加入
            map.get(sortKey).add(str);
        }

        // 3. 将map中所有分组集合转为最终结果返回
        return new ArrayList<>(map.values());
    }
}

思路:

创建map

循环遍历每个字符串,将每个取出然后排序作为key,接着就对接下来的是一样排序的字符串就加上去该key的list,表示就new一个这个key的空集合,用于存放和他排序一样的字符串

最后new一个返回值将map返回

最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n)的算法解决此问题。

示例 1:

复制代码
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

示例 2:

复制代码
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

示例 3:

复制代码
输入:nums = [1,0,1,2]
输出:3

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
java 复制代码
class Solution {
    public int longestConsecutive(int[] nums) {
         // 处理数组为空的边界
        if (nums == null || nums.length == 0) {
            return 0;
        }
        // 1. 创建哈希集合,存入所有数字,自动去重
        Set<Integer> numSet = new HashSet<>();
        for (int num : nums) {
            numSet.add(num);
        }
        int maxLength = 0;
        // 2. 遍历集合中每个数字
        for (int x : numSet) {
            // 判断:x-1不存在,说明x是连续序列起点
            if (!numSet.contains(x - 1)) {
                int currentNum = x;
                int currentLen = 1;
                // 不断往后找连续数字
                while (numSet.contains(currentNum + 1)) {
                    currentNum++;
                    currentLen++;
                }
                // 更新最大长度
                if (currentLen > maxLength) {
                    maxLength = currentLen;
                }
            }
        }
        return maxLength;
    }
}

完整逻辑流程

  1. 数组为空直接返回 0;
  2. 创建 HashSet 存入所有数字,去重;
  3. 定义最长长度 maxLen=0;
  4. 遍历集合中每个数字 x:
    • 如果集合不含 x-1 → x 是连续段起点
    • 当前长度 curLen=1,current=x
    • 循环判断 current+1 是否在集合:存在则 curLen++,current++
    • 更新 maxLen
  5. 遍历结束返回 maxLen