哈希表部分:
哈希表,简单来说就是k-v形式查询的结构,用来快速判断一个元素是否出现集合里,如hashmap
核心是哈希函数,k存哈希函数的值,找的时候找查询项的哈希函数值就行,返回v
出现哈希碰撞的时候,查找的流程怎么走呢?(*存疑,之后查一下)
类型:数组+集合set(set、multiset、unordered_set)+映射map(map、multimap、unordered_map)
使用:效率--unordered_set、有序不重复--set、有序可重复--multiset
242.有效的字母异位词
题目
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
第一想法
我觉得难点在于如何判断字符,次数的话统计的时候一个增一个减就行
假设用一个数组来记录,要怎么确定字符在前面出现过了呢
思路&题解
//需要定义一个多大的数组呢,定一个数组叫做record,大小为26 就可以了,初始化为0,
//因为字符a到字符z的ASCII也是26个连续的数值。 我只能说 ascii码太伟大了
class Solution {
public boolean isAnagram(String s, String t) {
int[] record = new int[26];
for (int i = 0; i < s.length(); i++) {
record[s.charAt(i) - 'a']++;
for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;
}
for (int count: record) {
if (count != 0) {
return false;
}
}
return true;
}
}
349.两个数组的交集
题目
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
第一想法
不重复--考虑set
思路&题解
//这里是纯纯忘了 hash系列的本质是空间换时间 这里没限制空间的使用,但没有想到可以用额外的hashset再记录
//数组数组 当然里面都是数字 脑子转不动了
import java.util.HashSet;
import java.util.Set;
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
// why...
if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) {
return new int[0];
}
Set<Integer> set1 = new HashSet<>();
Set<Integer> resSet = new HashSet<>();
//遍历数组1
for (int i : nums1) {
set1.add(i);
}
//遍历数组2的过程中判断哈希表中是否存在该元素
for (int i : nums2) {
if (set1.contains(i)) {
resSet.add(i);
}
}
return resSet.stream().mapToInt(x -> x).toArray();
}
}
19.快乐数
题目
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
第一想法
用一个数组存放各位,直到数组前面都是0最后一位是1
但是容易陷入死循环?
思路&题解
//题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
//判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止
//碳基生命能想得出来???
class Solution {
public boolean isHappy(int n){
Set<Integer> sumSet = new HashSet<Integer>();
while (n != 1 && !sumSet.contains(n)) {
sumSet.add(n);
n = getNextNumber(n);
}
return n == 1; //妙啊
}
//首先取到各位数
private int getNextNumber(int n) {
int sum = 0;
while (n > 0) {
int temp = n % 10;//余数
sum += temp * temp;
n = n / 10;//模 退位
}
return sum;
}
}
1.两数之和
题目
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
第一想法
第三次见你了,不知道这次能不能写得出来
思路&题解
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
int[] res = new int[2];
if(nums == null || nums.length == 0){
return res;
}
for (int i = 0; i<nums.length ; i++){
int dif = target-nums[i];
if(map.containsKey(dif)){
res[0] = i;
res[1] = map.get(dif);
break;
}
map.put(nums[i],i);//map的get方法只能拿到value,所以下标存value
}
return res;
}
}
文档讲解
https://www.programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
https://www.programmercarl.com/0242.%E6%9C%89%E6%95%88%E7%9A%84%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html
https://www.programmercarl.com/0349.%E4%B8%A4%E4%B8%AA%E6%95%B0%E7%BB%84%E7%9A%84%E4%BA%A4%E9%9B%86.html
https://www.programmercarl.com/0202.%E5%BF%AB%E4%B9%90%E6%95%B0.html
https://www.programmercarl.com/0001.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.html
视频讲解
https://www.bilibili.com/video/BV1YG411p7BA/?spm_id_from=333.788&vd_source=cf378ec519f76396d006e5f8b80218db
https://www.bilibili.com/video/BV1ba411S7wu/?spm_id_from=333.788&vd_source=cf378ec519f76396d006e5f8b80218db
https://www.bilibili.com/video/BV1aT41177mK/?spm_id_from=333.788&vd_source=cf378ec519f76396d006e5f8b80218db