学习目标:
60天训练营打卡计划!
学习内容:
- 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
- 当我们想使用哈希法来解决问题的时候,我们一般会选择如下三种数据结构。
- 数组
- set (集合)
- map(映射)
- 引用自代码随想录网站。
242.有效的字母异位词
- 使用数组来实现对应。
- 设置一个长度为26的int数组,有对应的字母就++
- 为了不记忆字母的ASCII码,使用该操作 tmp[s.charAt(i) - ‘a’]
- String的长度是length(),数组是length
- s.charAt(i) 是Java中取位置i处字符的函数
class Solution {
public boolean isAnagram(String s, String t) {
int[] tmp = new int[26];
// charAt(i)获取String中位置i的字符
for(int i = 0; i < s.length(); i++)
tmp[s.charAt(i) - 'a']++;
for(int j = 0; j < t.length(); j++)
tmp[t.charAt(j) - 'a']--;
for(int i = 0; i < 26; i++)
if(tmp[i] != 0){
return false;
}
return true;
}
}
349. 两个数组的交集
- 使用集合先对第一个数组中的元素去重,再使用第二个数组中的元素与其对比,若包含则放入第二个集合中(去重)!
- return reset.stream().mapToInt(x -> x).toArray();玩意就比较难
- 很多Java的集合的基本操作不是很熟悉,还需要多强化。
- 补充一点点相关的知识
Set 集合支持的遍历方式和 Collection 集合一样:foreach 和 Iterator。
Set 的常用实现类有:HashSet、TreeSet、LinkedHashSet。
• HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存储、查找、删除性能。
• HashSet 具有以下特点:
– 不能保证元素的排列顺序
– HashSet 不是线程安全的
– 集合元素可以是 null
• HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法得到的哈希值相等,并且两个对象的 equals()方法返回值为 true。
• 对于存放在 Set 容器中的对象,对应的类一定要重写 hashCode()和 equals(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。
• HashSet 集合中元素的无序性,不等同于随机性。这里的无序性与元素的添加位置有关。具体来说:我们在添加每一个元素到数组中时,具体的存储位置是由元素的hashCode()调用后返回的 hash 值决定的。导致在数组中每个元素不是依次紧密存放的,表现出一定的无序性。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
// Set<Integer> 作为变量类型可以使你的代码更加灵活,因为你可以随时切换不同的 Set 实现类
Set<Integer> unset = new HashSet();
Set<Integer> reset = new HashSet();
for(int i = 0; i < nums1.length; i++){
unset.add(nums1[i]);
}
for(int j = 0; j < nums2.length; j++){
if(unset.contains(nums2[j]))
reset.add(nums2[j]);
}
// 流中的每个元素进行映射操作。这里x -> x表示将元素映射为它自身。
// 将流中的元素收集到一个数组中。
return reset.stream().mapToInt(x -> x).toArray();
}
}
202. 快乐数
- 题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
- 需要二刷,并不是很快乐!
- 两个难点
-
- 如何获取int类型值得每一位数据?
-
- 使用余数获取各位的数值,使用商对数据做递减。
-
- 如何判定循环结束的条件?
-
- 无限循环,那么也就是说求和的过程中,sum会重复出现
class Solution {
public boolean isHappy(int n) {
Set set = new HashSet();
while(n != 1 && !set.contains(n)){
set.add(n);
n = getNum(n);
}
return n == 1;
}
private int getNum(int n){
int res = 0;
while(n > 0){
int tmp = n % 10;
res += tmp*tmp;
n /= 10;
}
return res;
}
}
1. 两数之和
-
暴力求解,yyds!
-
对java中map的基本操作不熟悉。
Map 接口的常用实现类:HashMap、LinkedHashMap、TreeMap 和Properties。其中,HashMap 是 Map 接口使用频率最高的实现类。
• 添加、修改操作:
– Object put(Object key,Object value):将指定 key-value 添加到(或修改)当前 map 对象中
– void putAll(Map m):将 m 中的所有 key-value 对存放到当前 map 中
• 删除操作:
– Object remove(Object key):移除指定 key 的 key-value 对,并返回 value
– void clear():清空当前 map 中的所有数据
• 元素查询的操作:
– Object get(Object key):获取指定 key 对应的 value
– boolean containsKey(Object key):是否包含指定的 key
– boolean containsValue(Object value):是否包含指定的 value
– int size():返回 map 中 key-value 对的个数
– boolean isEmpty():判断当前 map 是否为空
– boolean equals(Object obj):判断当前 map 和参数对象 obj 是否相等
• 元视图操作的方法:
– Set keySet():返回所有 key 构成的 Set 集合
– Collection values():返回所有 value 构成的 Collection 集合
– Set entrySet():返回所有 key-value 对构成的 Set 集合 -
一个难点
-
- map中的key存每一位的值,value存其的位置
-
- 使用余数获取各位的数值,使用商对数据做递减。
-
- 如何判定循环结束的条件?
-
- 无限循环,那么也就是说求和的过程中,sum会重复出现
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap();
map.put(nums[0] , 0);
int differ = -1;
for(int i = 1; i < nums.length; i++){
differ = target - nums[i];
if(map.containsKey(differ)){
return new int[]{map.get(differ),i};
}
map.put(nums[i],i);
}
return new int[2];
}
}
160. 链表相交
- 思路:一定要将两个链表的尾部对齐,因为如果相交的话,一定有共同的尾部。
- 先确认两个链表的长度!
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int num1 = 0;
int num2 = 0;
int count;
int min = 0;
while(curA != null){
curA = curA.next;
num1++;
}
while(curB != null){
curB = curB.next;
num2++;
}
// 重新指定头,并将长链表的头移动到短链表头的位置
curA = headA;
curB = headB;
if(num1 >= num2){
count = num1 - num2;
while(count-- > 0){
curA = curA.next;
}
}
else{
count = num2 - num1;
while(count-- > 0){
curB = curB.next;
}
}
min = Math.min(num1,num2);
while(min-- > 0){
if(curA == curB){
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
学习时间:
- 上午三小时,下午整理文档半小时