随想录训练营Day6|哈希表 242.有效的字母异位词, 349. 两个数组的交集,202. Happy Number,1. 两数之和
标签: LeetCode闯关记
##哈希表(Hash Table) 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法 常见的数据结构:
array;set;map; ##1. 242.有效的字母异位词 ###1.1 题目 相关链接: 242.有效的字母异位词
###1.2 解题思路 ①编写函数来判断t是否是s的字母异位词,可以看作判断字母是否出现在某个集合中_____考虑用hashSet;
②字母个数确定,题目描述可以把字符串假设为只包含小写字母,可以考虑用最简单的hashSet,即数组; ###1.3 遇到问题 无 ###1.4 算法实现
class Solution {
public boolean isAnagram(String s, String t) {
int[] record = new int[26];//26个字母数所以数组长度固定
//两次遍历并用新数组record记录便能够进行对比
for (int i = 0; i < s.length(); i++){
record[s.charAt(i) - 'a']++;
}//不必记录精确的ASCII码,用[s.charAt(i) - 'a']即可
for (int j = 0; j < t.length(); j++){
record[t.charAt(j) - 'a']--;
}
for (int n : record) {
if(n != 0){
return false;
}
}
return true;
}
注意点:待更新
###1.5 题目总结 解题耗时:30min ###1.6 相关题目 383.赎金信
49.字母异位词分组
438.找到字符串中所有字母异位词
##**2. 349. 两个数组的交集 **
###2.1 题目
题目:349. 两个数组的交集
###2.2 解题思路
题目:Each element in the result must be unique and you may return the result in any order.
引入新的构造体:SET
SET基本介绍:
1.无序(添加和取出的顺序不一致),没有索引;
2.不允许重复元素,所以最多只能包含一个null;
详见:韩顺平java(可补充链接)
用到的方法:
set.add();
set.contains();
###2.4 实现代码
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
if(nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0){
return new int[0];
}//nums1 == null 和 nums1.length == 0的区别
Set<Integer> set1 = new HashSet<>();
Set<Integer> resSet = new HashSet<>();
//遍历数组1
for (int number : nums1) {
set1.add(number);
}
//遍历数组2的过程中判断哈希表中是否存在该元素
for (int i : nums2) {
if(set1.contains(i)){
resSet.add(i);
}
}
int[] res = new int[resSet.size()];
int i = 0;
//利用迭代器遍历set
//另外申请一个数组存放setRes中的元素,最后返回数组
Iterator<Integer> iterator = resSet.iterator();
while (iterator.hasNext()) {
int next = iterator.next();
res[i] = next;
i++;
}
return res;
}
}
注意点: nums1 == null 和 nums1.length == 0是两个不同的判断条件,含义也不同。
(优先判断)nums1 == null 判断的是 nums1 是否为 null。 如果 nums1 是 null,则表示该数组变量没有被初始化,即该数组不存在,因此不能对其进行操作,包括读取、修改等。如果试图对其进行操作,会抛出 NullPointerException 异常。
nums1.length == 0 判断的是 nums1 是否为一个长度为0的数组。如果 nums1 是一个长度为0的数组,则表示该数组存在但是其中没有任何元素,可以对其进行读取和修改操作,但是其长度为0,无法进行遍历或者其他需要依赖于数组长度的操作。 ###2.5 题目总结 解题耗时: 40min ###2.6 相关题目 350.两个数组的交集 II
##3. 202. Happy Number ###3.1 题目 相关链接 202. Happy Number
###3.2 解题思路 repeat the process之后有两种情况,it loops endlessly in a cycle which does not include 1(会重复出现除了1之外的其他数) or ends in 1. 难点: 1.采用什么数据结构才能够很好地进行happy number 的计算和判断过程? 2.求和的过程:while循环 ###3.3 遇到问题 无 ###3.4 算法实现
class Solution {
public boolean isHappy(int n) {
Set<Integer> record = new HashSet<>();
while(n != 0 && ! record.contains(n)){
record.add(n);
n = getNextNumber(n);
}
return n == 1 ? true : false;//等价于 return n == 1;
}
private int getNextNumber(int n){
int temp = 0;
int sum = 0;
while(n > 0){
temp = n % 10;
sum += temp * temp;
n = n / 10;
}
return sum;
}
}
注意点: ①退出while循环的条件: n==1(说明是快乐数) 或者 n 出现循环(说明不是快乐数) ②return n == 1:表示 可以返回一个布尔值,因为这个语句使用了一个等于运算符 ==,它的结果要么是 true,要么是 false。具体来说,如果 n 等于1,则等于运算符的结果为 true,否则为 false。 ###3.5 题目总结 解题耗时:30min ###3.6 相关题目
##4. 1. 两数之和 ###4.1 题目 相关链接 1. 两数之和
###4.2 解题思路 1.why use the Map data structure? 首先,遍历数组时.我们需要判断当前遍历的数是否的target -nums[i]被遍历过,if yes,则找到了一组解; 所以,我们需要集合来存放遍历过的数,存放不仅要存元素,还需要存放下标 so, map可用来存放key,value 2. why use the unordered map? 不需要进行排序---HashMap效率更高
| Map 实现 | 适用场景 | 时间复杂度 |
|---|---|---|
| HashMap | 大部分情况,不需要排序和保持插入顺序的情况 | 平均为 O(1),最坏为 O(n) |
| TreeMap | 需要对 key 进行排序的情况 | 平均为 O(log n) |
| LinkedHashMap | 需要保持插入顺序的情况 | 平均度为 O(1),最坏为 O(n) |
| ConcurrentHashMap | 多线程环境下需要使用的情况 | 平均为 O(1),最坏为 O(log n) |
| IdentityHashMap | 需要基于对象引用进行相等性比较的情况 | 与 HashMap 相同 |
###4.3 遇到问题 无 ###4.4 算法实现
class Solution {
public int[] twoSum(int[] nums, int target) {
//新建hashmap
Map<Integer,Integer> valToIndex = new HashMap<>();
//遍历数组
int res = 0;
for( int i = 0; i < nums.length; i++){
res = target - nums[i];
//如果在存放遍历过的元素的hashmap中找到该res,返回
if(valToIndex.containsKey(res)){
return new int[]{valToIndex.get(res),i};
}else{//没找到的话,把当前遍历的数加入到hashmap中
valToIndex.put(nums[i],i);
}
}
return null;
}
}
##5. 今日心得 补3.20