代码随想录刷题Day7

58 阅读4分钟

哈希表

  1. 242. 有效的字母异位词
  • 方法一:排序法
class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        char[] a=s.toCharArray();//toCharArray()"是String类的一个方法,用于将字符串转换为一个字符数组。
        char[] b=t.toCharArray();
        Arrays.sort(a);
        Arrays.sort(b);
        for(int i=0;i<a.length;i++){//看了解析这一段可以优化为return Arrays.equals(a, b);
            if(a[i]!=b[i])
                return false;
        }
        return true;
    }
}
  • 方法二:哈希表

image.png

官方思路是先判断s和t长度是否相等,不相等肯定是false。再建一个哈希表,先遍历s把s的字符存到key,字符出现次数存到value,同样遍历t存进哈希表,如果出现value<0的情况,必然是false

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        Map<Character,Integer> map=new HashMap<>();
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);//检索s中的第i+1个字符
            map.put(ch,map.getOrDefault(ch,0)+1);//getOrDefault(key, default)如果存在key, 则返回其对应的value, 否则返回给定的默认值0 ,再+1即value存的是ch出现次数,
        }
        for(int i=0;i<t.length();i++){
            char ch=t.charAt(i);
            map.put(ch,map.getOrDefault(ch,0)-1);
            if(map.get(ch)<0){
                return false;
            }
        }
        return true;
    }
}

个人认为前面都没问题,s和t都存进了哈希表,那么遍历哈希表看看value有没有!=0的不就好了吗,我自己能理解的更清楚点

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        Map<Character,Integer> map=new HashMap<>();
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);//检索s中的第i+1个字符
            map.put(ch,map.getOrDefault(ch,0)+1);//getOrDefault(key, default)如果存在key, 则返回其对应的value, 否则返回给定的默认值0 ,再+1即value存的是ch出现次数,
        }
        for(int i=0;i<t.length();i++){
            char ch=t.charAt(i);
            map.put(ch,map.getOrDefault(ch,0)-1);
        }
        for(int a:map.values()){//遍历 map 中的所有value,每次迭代都会将一个value赋给变量 a
            if(a!=0){
                return false;
            }
        }
        return true;
    }
}
  1. 349. 两个数组的交集
  • 我的思路 HashMap+暴力

先把nums1和nums2都遍历一遍,把交点存到map。再把key的不重复集合赋给数组ans并返回。碰到这种题习惯就弄个HashMap,效率有点低。

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Map<Integer, Integer> map=new HashMap<>();
        for(int i=0;i<nums1.length;i++){
            if(map.containsKey(nums1[i])) continue;//map里有这个key了就跳到下一个循环
            for(int j=0;j<nums2.length;j++){
                if(nums1[i]==nums2[j]){//找到相交就存到map里
                    map.put(nums1[i],i);
                }
            }
        }
        int index=0;
        Set<Integer> res=map.keySet();//返回所有key的不重复集合res
        int[] ans = new int[res.size()];//这里要用size不能用length
        for(int i: res){//遍历res,存到数组ans
            ans[index]=i;
            index++;
        }
        return ans;
    }
}

代码随想录提供的两个方法

  • 第一种hashSet
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Set<Integer> set=new HashSet<>();
        Set<Integer> res=new HashSet<>();
        for(int i:nums1){//遍历数组1,存到set
            set.add(i);
        }
        for(int i:nums2){//遍历数组2
            if(set.contains(i)){//判断i是否存在set中,若存在,加入res
                res.add(i);
            }
        }
        int index=0;
        int[] ans = new int[res.size()];//size表示返回集合中元素个数
        for(int i: res){//遍历res,存到数组ans
            ans[index]=i;
            index++;
        }
        return ans;
    }
}
  • 第二种 哈希数组
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        int[] a = new int[1002];
        int[] b = new int[1002];
        for(int i : nums1)//把元素出现次数存在新数组A/B中
            a[i]++;
        for(int i : nums2)
            b[i]++;
        List<Integer> resList = new ArrayList<>();
        for(int i = 0; i < 1002; i++)//数组下标相同时且元素出现次数>0时即为相交,存入resList
            if(a[i] > 0 && b[i] > 0)
                resList.add(i);
        int index=0;
        int[] ans = new int[resList.size()];//size表示返回集合中元素个数
        for(int i: resList){//遍历res,存到数组ans
            ans[index]=i;
            index++;
        }
        return ans;
    }
}
  1. 202. 快乐数

只看了哈希法。 由题可知不停求和最终有两种可能,第一种会得到 1。第二种会进入循环。

那么思路:

1、做数位分离,求平方和。(我的思路是字符转换)

2、可以使用哈希集合完成。每次生成链中的下一个数字时,我们都会检查它是否已经在哈希集合中。

  • 如果它不在哈希集合中,我们应该添加它。
  • 如果它在哈希集合中,这意味着我们处于一个循环中,因此应该返回 false
class Solution {
    //求n每个位数的平方和
    public static int getSum(int n){
        String s = String.valueOf(n);
        int sum=0;
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);
            int a = Integer.parseInt(String.valueOf(ch));
            sum+=Math.pow(a,2);
        }
        return sum;
    }
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        while(!set.contains(n)){//判断n有没有出现在set里,出现了则直接false
            int sum=getSum(n);
            if(sum==1){
                return true;
            }else{
                set.add(n);//把没出现过的加入set
            }
            n=sum;//sum赋值给n,进入下一轮判断
        }
        return false;
    }
}