hot100笔记-哈希

1.两数之和

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

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

思路:使用哈希表存储数和对应下标,遍历的同时进行寻找

class Solution {
    public int[] twoSum(int[] nums, int target) {
        // 使用HashMap来存储数组中的元素及其对应的索引
        Map<Integer, Integer> map = new HashMap<>();
​
        
        for (int i = 0; i < nums.length; i++) {
            // 计算当前元素与目标值的差值
            int complement = target - nums[i];
​
            // 检查HashMap中是否已经存在这个差值
            if (map.containsKey(complement)) {
                // 如果存在,说明找到了两个数的和等于目标值
                // 返回这两个数的索引
                return new int[]{map.get(complement), i};
            }
​
            // 如果不存在,将当前元素及其索引存入HashMap
            map.put(nums[i], i);
        }
​
        // 如果遍历完数组仍未找到满足条件的两个数,返回空数组
        return new int[0];
    }
}

49.字母异位词分组

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

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

思路:将每个字符串排序后作为键,所有排序后得到相同键的字符串即为一组异位词。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 创建一个哈希映射,键是排序后的字符串,值是所有对应的异位词
        Map<String, List<String>> map = new HashMap<>();
        List<List<String>> res = new ArrayList<>(); // 用于存储最终的分组结果
​
        // 遍历输入的字符串数组
        for (String str : strs) {
            // 将当前字符串转换为排序后的键
            String key = getKey(str);
​
            // 检查哈希映射中是否已经存在该键
            if (map.containsKey(key)) {
                // 如果存在,直接将当前字符串添加到对应的列表中
                List<String> list = map.get(key);
                list.add(str);
            } else {
                // 如果不存在,创建一个新的列表,将当前字符串加入,并将键值对存入哈希映射
                List<String> list = new ArrayList<>();
                list.add(str);
                map.put(key, list);
                res.add(list); // 同时将该列表加入到结果列表中
            }
        }
​
        // 返回最终的分组结果
        return res;
    }
​
    // 辅助方法:将字符串排序后生成键
    public String getKey(String str) {
        // 将字符串转换为字符数组
        char[] array = str.toCharArray();
        // 对字符数组进行排序
        Arrays.sort(array);
        // 将排序后的字符数组重新转换为字符串作为键
        return new String(array);
    }
}

128. 最长连续序列

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

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

哈希法:对于nums中的元素x,以x为起点,不断查找下一个数x+1,x+2,⋯是否在nums中,并统计序列的长度。

class Solution {
    public int longestConsecutive(int[] nums) {
        int ans = 0;
        Set<Integer> st = new HashSet<>();
        for (int num : nums) {
            st.add(num); // 把 nums 转成哈希集合
        }
        for (int x : st) { // 遍历哈希集合
            if (st.contains(x - 1)) {
                continue;
            }
            // x 是序列的起点
            int y = x + 1;
            while (st.contains(y)) { // 不断查找下一个数是否在哈希集合中
                y++;
            }
            // 循环结束后,y-1 是最后一个在哈希集合中的数
            ans = Math.max(ans, y - x); // 从 x 到 y-1 一共 y-x 个数
        }
        return ans;
    }
}
排序
class Solution {
    public int longestConsecutive(int[] nums) {
        Arrays.sort(nums);// 排序数组
        int maxCount = 1; // 最长连续序列长度
        int count = 1;   // 当前连续序列长度
        if(nums.length == 0){
            return 0;
        }
​
        for(int i = 0;i < nums.length - 1;i++){
            if(nums[i] == nums[i + 1]){
                 // 忽略重复的数字
                continue;
            }
            else if(nums[i + 1] - nums[i] == 1){
                // 如果当前数字与下一个数字连续,增加计数
                count++;
            }
            else{
                // 不连续时,更新最大长度并重置计数
                maxCount = Math.max(maxCount, count);
                count = 1;
            }
        }
        // 最后一次更新最大长度
        maxCount = Math.max(maxCount, count);
        return maxCount;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值