LeetCode之哈希表

383. 赎金信

java 复制代码
class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        // 创建一个 HashMap 来存储 magazine 中字符出现的次数
        Map<Character, Integer> map = new HashMap<>();
        
        // 遍历 magazine 字符串,将每个字符及其出现的次数存入 map 中
        for (char c : magazine.toCharArray()) {
            // 如果字符 c 已经在 map 中,将其对应的值加 1
            // 如果字符 c 不在 map 中,将其添加到 map 中并初始化为 0 ,然后加 1
            map.put(c, map.getOrDefault(c, 0) + 1);
        }

        // 遍历 ransomNote 字符串
        for (char r : ransomNote.toCharArray()) {
            // 如果 map 中字符 c 的出现次数为 0 ,说明无法构建 ransomNote ,返回 false
            if (map.getOrDefault(r, 0) == 0) {
                return false;
            }
            // 如果字符 c 的出现次数不为 0 ,则将其对应的值减 1
            map.put(r, map.getOrDefault(r, 0) - 1);
        }
        // 如果遍历完 ransomNote 都没有出现无法构建的情况,返回 true
        return true;
    }
}

205. 同构字符串

java 复制代码
class Solution {

    public boolean isIsomorphic(String s, String t) {
        // 创建两个哈希表,分别用于存储 s 到 t 和 t 到 s 的映射
        Map<Character, Character> s2t = new HashMap<>();
        Map<Character, Character> t2s = new HashMap<>();

        // 获取字符串的长度
        int len = s.length();

        // 遍历每个字符
        for (int i = 0; i < len; i++) {
            // 获取 s 和 t 中对应位置的字符
            char x = s.charAt(i);
            char y = t.charAt(i);

            // 检查当前字符 x 是否已经在 s2t 中映射到一个不同的字符 y
            // 同时检查字符 y 是否已经在 t2s 中映射到一个不同的字符 x
            if ((s2t.containsKey(x) && s2t.get(x) != y) || (t2s.containsKey(y) && t2s.get(y) != x)) {
                // 如果发现不一致,返回 false
                return false;
            }
            // 如果没有冲突,更新映射
            // x 映射到 y
            s2t.put(x, y);
            // y 映射到 x
            t2s.put(y, x);
        }

        // 如果遍历完都没有冲突,返回 true
        return true;
    }

}

290. 单词规律

java 复制代码
class Solution {

    public boolean wordPattern(String pattern, String s) {
        // pattern = "abba", s = "dog cat cat dog" true

        // 输入的模式是 "abba",字符串是 "dog cat cat dog",返回 true
        // 将字符串 s 按空格分割成数组
        String[] arr = s.split(" ");
        // 如果模式长度与分割后的数组长度不相等,返回 false
        if (pattern.length() != arr.length) {
            return false;
        }

        // 创建两个映射,用于模式到字符串和字符串到模式的映射
        Map<Character, String> p2s = new HashMap<>();
        Map<String, Character> s2p = new HashMap<>();

        // 遍历模式和对应的字符串
        for (int i = 0; i < arr.length; i++) {
            // 获取当前模式字符
            char p = pattern.charAt(i);
            // 获取当前分割后的字符串
            String str = arr[i];
            // 检查模式字符和字符串的映射是否一致
            // 如果模式字符已经存在于 p2s 映射中且对应的字符串不匹配,返回 false
            // 如果字符串已经存在于 s2p 映射中且对应的模式字符不匹配,返回 false
            if ((p2s.containsKey(p) && !p2s.get(p).equals(str)) || (s2p.containsKey(str) && !s2p.get(str).equals(p))) {
                return false;
            }
            // 建立新的映射关系
            // 将模式字符映射到字符串
            p2s.put(p, str);
            // 将字符串映射到模式字符
            s2p.put(str, p);
        }

        // 如果遍历完所有字符都没有不匹配的情况,返回 true
        return true;
    }
    
}

242. 有效的字母异位词

java 复制代码
class Solution {

    // 定义一个方法来判断两个字符串是否为字母异位词(即包含相同字符,但顺序不同)
    public boolean isAnagram(String s, String t) {
        // s = "anagram", t = "nagaram" true
        // 如果两个字符串的长度不同,直接返回 false
        if (s.length() != t.length()) {
            return false;
        }
        // 使用 HashMap 来存储字符及其出现次数
        Map<Character, Integer> map = new HashMap<>();
        // 遍历字符串 s,记录每个字符的出现次数
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 更新 HashMap 中该字符的计数
            map.put(c, map.getOrDefault(c, 0) + 1);
        }

        // 遍历字符串 t,减少对应字符的出现次数
        for (int i = 0; i < t.length(); i++) {
            char c = t.charAt(i);
            // 在 HashMap 中将该字符的计数减一
            map.put(c, map.getOrDefault(c, 0) - 1);
            // 如果某个字符的计数小于零,说明 t 中的该字符超过了 s 中的数量,返回 false
            if (map.get(c) < 0) {
                return false;
            }
        }
        // 如果所有字符的计数都正确,返回 true,表示 s 和 t 为字母异位词
        return true;
    }

}

49. 字母异位词分组

java 复制代码
class Solution {

    // 方法 groupAnagrams 接收一个字符串数组 strs,返回字谜的分组列表
    public List<List<String>> groupAnagrams(String[] strs) {
        // 创建一个 Maps,用于将排序后的字符串作为关键字,与列表关联
        Map<String, List<String>> map = new HashMap<>();

        // 遍历字符串数组中的每个字符串
        for (String str : strs) {
            // 将字符串转换为字符数组
            char[] arr = str.toCharArray();
            // 对字符数组进行排序
            Arrays.sort(arr);
            System.out.println(Arrays.toString(arr));
            // 将排序后的字符数组重新转换为字符串作为键
            String key = new String(arr);
            System.out.println(key);

            // 根据键从 map 中获取对应的字谜列表,如果不存在则初始化一个新的列表
            List<String> list = map.getOrDefault(key, new ArrayList<>());
            // 将当前字符串加入到对应的字列表中
            list.add(str);
            // 将更新后的列表放回 map 中
            map.put(key, list);
        }
        // 返回 map 中所有值的列表,转换为 List<List<String>> 类型
        return new ArrayList<>(map.values());
    }

}

1. 两数之和

java 复制代码
class Solution {

    /**
     * 两数之和

     * @nums 整数数组
     * @target  目标值
     */
    public int[] twoSum(int[] nums, int target) {
        // 创建一个用于存储数字及其索引的 HashMap
        Map<Integer, Integer> map = new HashMap<>();
        // 遍历数组 
        for (int i = 0; i < nums.length; i++) {
            // 如果 HashMap 中包含目标值减去当前数字的差值
            if (map.containsKey(target - nums[i])) {
                // 返回当前索引和差值对应的索引
                return new int[]{i, map.get(target - nums[i])};
            }
            // 将当前数字及其索引存入 HashMap
            map.put(nums[i], i);
        }
        // 如果遍历完数组都未找到,返回空数组
        return new int[0];
    }

}

202. 快乐数

java 复制代码
class Solution {

    /**
     * 判断一个整数是否为快乐数
     
     * @param n 待判断的整数
     * @return 如果是快乐数返回 true,否则返回 false
     */
    public boolean isHappy(int n) {
        // 创建一个 HashSet 用于存储出现过的数字
        Set<Integer> set = new HashSet<>();
        
        // 当 n 不等于 1 且 n 未曾出现过时,执行循环
        // (为什么要判断是否在集合内,因为在集合内,就会陷入无限循环)
        while(n != 1 && !set.contains(n)) {
            // 将当前 n 加入 HashSet 中
            set.add(n);
            // 计算 n 的下一个数字
            n = getNext(n);
        }
        // 返回 n 是否等于 1
        return n == 1;
    }

    /**
     * 计算给定整数的下一个数字

     * @param n 输入的整数
     * @return 计算得到的下一个数字
     */
    private int getNext(int n) {
        int sum = 0;
        int cur = 0;
        // 当 n 大于 0 时
        while(n > 0) {
            // 获取 n 的最后一位数字
            cur = n % 10;
            // 去掉 n 的最后一位数字
            n = n / 10;
            // 计算当前数字的平方并累加到 sum 中
            sum = sum + cur * cur;
        }
        // 返回计算得到的下一个数字
        return sum;
    }
}

219. 存在重复元素 II

java 复制代码
class Solution {
    /**
     * 检查给定整数数组中是否存在两个相同元素,其索引之差不超过给定值 k
     * 
     * @param nums 整数数组
     * @param k 最大索引差
     * @return 如果存在这样的重复元素返回 true,否则返回 false
     */
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        // 创建一个 HashMap 用于存储元素及其对应的索引
        Map<Integer, Integer> map = new HashMap<>();

        // 遍历数组
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            // 如果 HashMap 中已包含当前元素,并且当前索引与之前存储的索引之差小于等于 k
            if (map.containsKey(num) && i - map.get(num) <= k) {
                return true;
            }
            // 将当前元素及其索引存入 HashMap
            map.put(num, i);
        }
        // 如果遍历完都未找到满足条件的重复元素,返回 false
        return false;

    }
}

128. 最长连续序列

java 复制代码
class Solution {
    public int longestConsecutive(int[] nums) {
        // 创建一个 HashSet 用于存储数组中的元素,以便快速查找元素是否存在
        Set<Integer> num_set = new HashSet<Integer>();
        for (int num : nums) {
            num_set.add(num);
        }

        // 用于记录最长连续序列的长度
        int longestStreak = 0;

        for (int num : num_set) {
            // 如果当前数字的前一个数字不存在,说明当前数字可能是一个连续序列的起始数字
            if (!num_set.contains(num - 1)) {
                int currentNum = num;
                // 记录当前连续序列的长度,初始为 1
                int currentStreak = 1;

                // 当当前数字的下一个数字存在于集合中时,继续增加当前连续序列的长度
                while (num_set.contains(currentNum + 1)) {
                    currentNum += 1;
                    currentStreak += 1;
                }

                // 更新最长连续序列的长度
                longestStreak = Math.max(longestStreak, currentStreak);
            }
        }

        return longestStreak;
    }
}
相关推荐
算法歌者14 分钟前
[算法]入门1.矩阵转置
算法
林开落L29 分钟前
前缀和算法习题篇(上)
c++·算法·leetcode
远望清一色30 分钟前
基于MATLAB边缘检测博文
开发语言·算法·matlab
tyler_download31 分钟前
手撸 chatgpt 大模型:简述 LLM 的架构,算法和训练流程
算法·chatgpt
SoraLuna1 小时前
「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
算法·macos·动态规划·cangjie
我狠狠地刷刷刷刷刷1 小时前
中文分词模拟器
开发语言·python·算法
鸽鸽程序猿1 小时前
【算法】【优选算法】前缀和(上)
java·算法·前缀和
九圣残炎1 小时前
【从零开始的LeetCode-算法】2559. 统计范围内的元音字符串数
java·算法·leetcode
YSRM1 小时前
Experimental Analysis of Dedicated GPU in Virtual Framework using vGPU 论文分析
算法·gpu算力·vgpu·pci直通
韭菜盖饭2 小时前
LeetCode每日一题3261---统计满足 K 约束的子字符串数量 II
数据结构·算法·leetcode