242. 有效的字母异位词349. 两个数组的交集

242. 有效的字母异位词

题目链接 有效的字母异位词

题目描述

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false

思路

  • 选择使用数组,数组就是简单的哈希表,而不是使用HashSet,HashMap
    元素的范围小,只有0-25,
  • 字符映射为哈希数组的索引,数组元素存放26个字符出现的次数
  • 先对s进行遍历,哈希数组存放s中出现的各种字符的次数
  • 再对t进行遍历,减去t中各种字符的出现次数
  • 若哈希数组元素全为0,则s和t互为字母异位词

代码

点击查看代码
//用数组(哈希表),也叫字典解法
//时间复杂度为O(n+m)
class Solution {
    public boolean isAnagram(String s, String t) {
		//字符串的长度不同则返回false
        if (s.length() != t.length())
            return false;
       int []hash = new int[26];
        for (int i = 0; i < s.length(); i++) {
		//通过哈希函数:(字符-97),返回哈希值作为哈希数组的索引
		//记录字符串s的字符出现的次数
		//减去字符串t的字符出现的次数
            hash[s.charAt(i)-'a']++;
            hash[t.charAt(i)-'a']--;
        }
        for (int i = 0; i < hash.length; i++) {
            //一旦hash中有一个元素不为0,返回false
			if(hash[i]!=0){
                return false;
            }
        }
		//hash[]中所有元素都是0
        return true;
    }
}

总结

对哈希表的相关知识比较淡薄,需要多去接触哈希表

  • 学会该数据结构的设计
  • 解决更多的哈希表相关的题目,了解选择数组,Hashset,HashMap的应用场景。

349. 两个数组的交集

题目链接 349. 两个数组的交集

题目描述

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000

思路

  • 选择哈希结构
  • 数组。两个数组中的元素值均不超过1000(对应的存储空间不大),可以用数组来解决:nums1转为哈希数组,数组元素值为1表示原数组中出现过该值,用nums2数组中的元素值作为哈希数组的索引查找是否出现过,出现过则将该nums2的元素值放入结果集
  • Set。适用于索引比较分散的情况如1,5,100000
    nums1转化为哈希表,遍历nums2再去哈希表查是否出现过,出现过则放入result(去重的结果集)

代码

第一做的代码:

点击查看代码
//时间复杂度O(n^2)
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> set = new HashSet<Integer>();
        //将交集放入HashSet
        for (int i = 0; i < nums1.length; i++) {
            for (int j = 0; j < nums2.length; j++) {
                if (nums1[i] == nums2[j]) {
                    set.add(nums1[i]);
                    break;
                }
            }
        }
        //hashSet转化为int数组
        int arr[] = new int[set.size()];
        int n = 0;
        Iterator it = set.iterator();
        while (it.hasNext()) {
            //由object转为int
            arr[n] = (int) it.next();
            n++;
        }
        return arr;
    }
}

Set解法

点击查看代码
//时间复杂度O(nums1.length + nums2.length + result.size())
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
         Set<Integer> result = new HashSet();
        Set nums1Set = new HashSet();
        //将nums1放入哈希表
        for (int i : nums1) {
            nums1Set.add(i);
        }
		//遍历nums2,若有和nums1Set相同的元素则添加进result
        for (int i : nums2) {
            if (nums1Set.contains(i)){
                result.add(i);
            }
        }
		//将reslut转换为int数组arr进行返回
        int []arr = new int[result.size()];
        int j=0;
        for (int i :
                result) {
            arr[j++] = i;
        }
        return arr;
    }
}

数组解法

点击查看代码
//时间复杂度O(nums1.length + nums2.length + result.size())
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
		//使用给结果集去重的Set
        Set<Integer> result = new HashSet();
        int hash[] = new int[1001];
        for (int i = 0; i < nums1.length; i++) {
            hash[nums1[i]] = 1;
        }
        for (int i = 0; i < nums2.length; i++) {
            if (hash[nums2[i]] == 1) {
                result.add(nums2[i]);
            }
        }
        int arr[] = new int[result.size()];
        int j = 0;
        for (int i :
                result) {
            arr[j++] = i;
        }
        return arr;
    }
}

总结

  • 哈希表最擅长的场景:查看某个元素是否在集合中出现过
  • 哈希值,是哈希函数得到的返回值,通常作为哈希表的索引
  • 如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
  • 直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。在数据量大的情况,两者差距是很明显的。
posted @ 2023-08-18 17:15  像峰一样  阅读(19)  评论(0)    收藏  举报