【力扣-刷题——哈希表】(242、383、49、438、)后续补充

105 篇文章 1 订阅
101 篇文章 1 订阅

目录

基础知识

来吧!一文彻底搞定哈希表!

  • 哈希表是根据关键码的值而直接进行访问的数据结构。

  • 一般哈希表都是用来快速判断一个元素是否出现集合里。

哈希函数

在这里插入图片描述

总结
总结一下,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

242. 有效的字母异位词——简单

力扣

给定两个字符串 st ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 st 中每个字符出现的次数都相同,则称 st 互为字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true

示例 2:

输入: s = "rat", t = "car"
输出: false


class Solution {
    public boolean isAnagram(String s, String t) {
        //判断是否相等
        if(s.length() != t.length()) return false;
        //存入 减去
        int[] a = new int[26];
        for(int i=0; i<s.length(); ++i){
            a[s.charAt(i)-'a']++;
            a[t.charAt(i)-'a']--;
        }

        // 判断结果是否为0
        for(int i=0; i<26; ++i){
            if(a[i] != 0) return false;
        }
        return true;
    }
}

383. 赎金信_简单

力扣

给你两个字符串:ransomNotemagazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false

magazine 中的每个字符只能在 ransomNote 中使用一次。

示例 1:

输入:ransomNote = "a", magazine = "b"
输出:false

示例 2:

输入:ransomNote = "aa", magazine = "ab"
输出:false

示例 3:

输入:ransomNote = "aa", magazine = "aab"
输出:true


class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        if(ransomNote.length() > magazine.length()) return false;

        int[] a = new int[26];
        for(char i : magazine.toCharArray()){
            a[i -'a']++;
        }
        for(char i : ransomNote.toCharArray()){
            a[i-'a']--;
            if(a[i-'a'] < 0){
                return false;
            }  
        }
        return true;
    }
}

49. 字母异位词分组——中等

力扣

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

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。

示例 1:

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

示例 2:

输入: strs = [""]
输出: [[""]]

示例 3:

输入: strs = ["a"]
输出: [["a"]]

1、排序

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        // 存放字符串
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        for(String str : strs){
            // 将字符串换为数组
            char[] array = str.toCharArray();
            // 数组排序
            Arrays.sort(array);
            // 返回字符串
            String key = new String(array);
            // 判断数组里有字符串吗
            List<String> list = map.getOrDefault(key, new ArrayList<String>());
            list.add(str);
            map.put(key, list);
        }
        return new ArrayList<List<String>>(map.values());
    }
}

2、stream 的 grouping

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
//         // stream 的 groupingBy
//         // groupingBy 算子计算完以后,返回的是一个 Map<String, List<String>>
//         // Collector是专门用来作为Stream的collect方法的参数的。
//         // collect 可以收集流中的数据到【集合】或者数组中去
//         // groupingBy 根据字符串进行分组
        return new ArrayList<>(Arrays.stream(strs)
            .collect(Collectors.groupingBy(
                str->{
                    //将str转换为数组
                    char[] array = str.toCharArray();
                    //排序
                    Arrays.sort(array);
                    //返回排序后的数组
                    return new String(array);
                }
            )).values()
        );
    }
}

438. 找到字符串中所有字母异位词——中等

给定两个字符串 sp,找到 s 中所有 p异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。

示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

方法一:滑动窗口

class Solution {
    //方法一:滑动窗口
    public List<Integer> findAnagrams(String s, String p) {
        // 字符串长
        int slen = s.length();
        int plen = p.length();
        // s<p 直接返回
        if(slen < plen ){
            return new ArrayList<Integer>();
        }
        // 定义数组存索引
        List<Integer> num = new ArrayList<Integer>();
        // 定义两个数组存字符串
        int[] sCount = new int[26];
        int[] pCount = new int[26];
        
        // 先判断开始是否与p相同,返回0
        for(int i=0; i<plen; ++i){
            ++sCount[s.charAt(i)-'a'];
            ++pCount[p.charAt(i)-'a'];
        }
        if(Arrays.equals(sCount,pCount)){
            num.add(0);
        }
        // 继续判断下一位
        for(int i=0; i<slen-plen; ++i){
            --sCount[s.charAt(i)-'a'];
            ++sCount[s.charAt(i+plen)-'a'];
            if(Arrays.equals(sCount,pCount)){
                num.add(i+1);
            }
        }
        return num;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值