代码随想录刷题-哈希表(上)

本文是每天跟着代码随想录刷题时做的笔记,用来总结与复习。

目录

242.有效的字母异位词

383.赎金信

49.字母异位词分组

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

349.两个数组的交集

今日总结

242.有效的字母异位词

题目链接:242. 有效的字母异位词 - 力扣(LeetCode) (leetcode-cn.com)

思路:

维护一个长度为 26 的数组 ans ,小写字母减去 'a' 就是其在数组中的位置,数组中存放对应字母的个数,遍历字符串 s 和 t,s 的字符使得 ans 数组对应位置加一,t 的字符使得 ans 数组对应位置减一(这里谁加一,谁减一其实是不做要求的),最后如果 ans 数组中的值全为 0 ,就表示 s 和 t 互为字母异位词。

	public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()){
            return false;
        }
        int[] ans = new int[26];
        char[] sArr = s.toCharArray();
        char[] tArr = t.toCharArray();
        for (int i = 0; i < s.length(); i++){
            ans[sArr[i] - 'a']++;
            ans[tArr[i] - 'a']--;
        }
        for (int i = 0; i < ans.length; i++) {
            if (ans[i] != 0){
                return false;
            }
        }
        return true;
    }

383.赎金信

题目链接:383. 赎金信 - 力扣(LeetCode) (leetcode-cn.com)

思路:

此题其实和 242 题思路差不多,只是在本题中我们应使用 magazine 中的字符来使 ans 数组对应位置加一,使用 ransomNote 中的字符来时 ans 数组对应位置减一,最后 ans 数组中的值如果不小于 0 ,就表明这两个字符满足题意。

	public boolean canConstruct(String ransomNote, String magazine) {
        int[] ans = new int[26];
        char[] sArr = ransomNote.toCharArray();
        char[] tArr = magazine.toCharArray();
        for(int i=0;i<26;i++){
            ans[i]=0;
        }
        for (int i = 0; i < magazine.length(); i++){
            ans[tArr[i] - 'a']++;
        }
        for (int i = 0; i < ransomNote.length(); i++) {
            ans[sArr[i] - 'a']--;
        }
        for (int i = 0; i < 26; i++) {
            if (ans[i] < 0){
                return false;
            }
        }
        return true;
    }

49.字母异位词分组

题目链接:49. 字母异位词分组 - 力扣(LeetCode) (leetcode-cn.com)

这道题我自己先做的时候运行时间如下。。。

后面参考着题解做了一次,我是fw。。。

题解思路:

字母异位词其实有个特点,就是排序后的字符串内容是一样的,因此我们可以将排序后相同的字符串用一个链表存储在一起,然后创建一个 map 集合,key 为排序后的字符串,value 就为该链表,这样可以完成分组。

	public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> map = new HashMap<>();
        for (int i = 0; i < strs.length; i++) {
            char[] chars = strs[i].toCharArray();
            Arrays.sort(chars);
            String s = new String(chars);
            List<String> list = map.getOrDefault(s, new ArrayList<>());
            list.add(strs[i]);
            map.put(s, list);
        }
        return new ArrayList<List<String>>(map.values());
    }

 踩坑:我在将 chars 转换为 String 类型时,误把 toString() 方法想成是可以将字符类型的数组转化为字符串的方法了,导致排错排了很久。。。

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

题目链接:438. 找到字符串中所有字母异位词 - 力扣(LeetCode) (leetcode-cn.com)

自己写。。。

题解,今日fw+1

题解思路:固定长度的滑动窗口

给 s 和 p 分别创建一个长度为 26 的数组 sArr 和 pArr,原理与 242 题中的 ans 数组一样,sArr 用来记录窗口中每种字符的数量,pArr 用来记录 p 中每种字符的数量。构造一个和 p 长度相同的滑动窗口,窗口在 s 上滑动,每滑动一次就修改 sArr,并判断 sArr 是否和 pArr 存储的每种字母的数量是否相同,相同则表明当前窗口为 p 的字母异位词。

	public List<Integer> findAnagrams(String s, String p) {
       List<Integer> ansList = new ArrayList<>();
       if (s.length() < p.length()){
           return ansList;
       }
       int[] pArr = new int[26];
       int[] sArr = new int[26];
       for (int i = 0; i  < p.length(); i++){
           pArr[p.charAt(i) - 'a']++;
           sArr[s.charAt(i) - 'a']++;
       }
       if (Arrays.equals(pArr,sArr)){
           ansList.add(0);
       }
       for (int i = 0; i < s.length() - p.length(); i++){
           sArr[s.charAt(i) - 'a']--;
           sArr[s.charAt(i + p.length()) - 'a']++;
           if (Arrays.equals(pArr, sArr)){
               ansList.add(i + 1);
           }
       }
       return ansList;
    }

349.两个数组的交集

题目链接:349. 两个数组的交集 - 力扣(LeetCode) (leetcode-cn.com)

最后一题来个 easy ,让自己睡个好觉

思路:用 map 将一个其中一个数组的所有元素作为 key 存入,判断另一个数组中的元素是否为 map 的 key ,如果是,存入一个 set 集合中保证不出现重复,最后将 set 集合转化为数组输出即可。

    public int[] intersection(int[] nums1, int[] nums2){
        Map<Integer,Integer> map = new HashMap<>();
        Set<Integer> ansSet = new HashSet<>();
        for (int i = 0; i < nums1.length; i++){
            map.put(nums1[i], 1);
        }
        for (int i = 0; i < nums2.length; i++){
            if (map.containsKey(nums2[i])){
                ansSet.add(nums2[i]);
            }
        }
        int[] ansArr = new int[ansSet.size()];
        int flag = 0;
        Iterator<Integer> iterator = ansSet.iterator();
        while (iterator.hasNext()){
            ansArr[flag++] = iterator.next();
        }
        return ansArr;
    }

今日总结

在做题时得发散思维,就像 438 这道题,明明之前还做过滑动窗口的题,在做这道题时也没有想到滑动窗口思路。

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值