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计算的。在数据量大的情况,两者差距是很明显的。
本文来自博客园,作者:像峰一样,转载请注明原文链接:https://www.cnblogs.com/peak-like/articles/17640226.html

刷题第7天:我与哈希表
浙公网安备 33010602011771号