242 有效的字母异位词
思路
定义一个有26个位置的数组,因为字母共有26个
对于单词s和t, 在扫描s的时候,记录每个单词出现的个数保存到数组
在扫描s的时候,操作同一个数组,对出现的每个字母对应的数组上所保存的个数上进行减减操作
如果数组最后所有位置上全为0,说明s和t互为异位词
题解
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']++; // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
}
for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;
}
for (int count: record) {
if (count != 0) { // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
return false;
}
}
return true; // record数组所有元素都为零0,说明字符串s和t是字母异位词
}
}
349 两个数组的交集
思路
首先将数组1的值存到Set1中,然后遍历数组2,如果数组2中的值在Set1中出现,那么将值存到Set2中,最后将Set2中的值存到新数组并返回。
注意:
set不仅占用空间比数组大,而且速度比数组慢,因为set把数值映射到key上都要做hash计算的。在数据量大的情况下,差距会很明显。
数组作哈希表-题解
因为数据范围为 0 <= num1[i], num2[i] <= 1000,所以可以使用数组来做哈希表。
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> resSet = new HashSet<>();
int[] hash = new int[1010];
for (int i : nums1){
hash[i] = 1;
}
for (int i : nums2){
if (hash[i] == 1){
resSet.add(i);
}
}
int[] resArr = new int[resSet.size()];
int j = 0;
for(int i : resSet){
resArr[j ++] = i;
}
return resArr;
}
}
HashSet-题解
java中HashSet的特点:
1)HashSet实现了Set接口
2)HashSet实际上是HashMap
3)可以存放null值,但是只能有一个null
4)HashSet不保证元素是有序的,取决于hash后,再确定索引的结果即不保证存放元素的顺序和取出元素一致
5) 不能有重复元素/对象
分割线
- HashSet 底层是 HashMap
2.添加一个元素时,先得到hash值-会转成-> 索引值
3.找到存储数据表table,看这个索引位置是否已经存放的有元素
4.如果没有,直接加入
5.如果有,调用equals 比较,如果相同,就放弃添加,如果不相同,则添加到最后
6.在Java8中,如果一条链表的元素个数超过 TREEIFY THRESHOLD(默认是8),并且table的大小
=MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
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<>();
for (int i : nums1){
set1.add(i);
}
for (int i : nums2){
if (set1.contains(i)){
resSet.add(i);
}
}
int[] resArr = new int[resSet.size()];
int j = 0;
for (int i : resSet){
resArr[j++] = i;
}
return resArr;
}
}
快乐数
思路
如果出现了无限循环,说明在求和的过程中,sum会重复出现。那么我们每次保存sum的值,使用HashSet保存,在保存之前判断sum是否已经存在,如果存在,说明出现了无限循环,那么return n == 1来判断n是否为快乐数。
题解
class Solution {
public boolean isHappy(int n) {
Set<Integer> record = new HashSet<>();
while (!record.contains(n)){
record.add(n);
n = getNextNum(n);
}
return n == 1;
}
private int getNextNum(int n){
int res = 0;
while (n > 0){
int temp = n % 10;
res += temp * temp;
n = n / 10;
}
return res;
}
}
1 两数之和
思路
题目要求返回满足条件的数组索引位置
使用map存入,key存数组值,value存数组下标。
在遍历数据的时候,每遍历一个,把遍历过的数值存到map的key里,下标存到map的value里
在存入之间,在map里查找是否有target-nums[i]的值,因为是对值查找,所以map的key存放数值
题解
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if(nums == null || nums.length == 0){
return res;
}
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
int temp = target - nums[i]; // 遍历当前元素,并在map中寻找是否有匹配的key
if(map.containsKey(temp)){
res[1] = i;
res[0] = map.get(temp);
break;
}
map.put(nums[i], i); // 如果没找到匹配对,就把访问过的元素和下标加入到map中
}
return res;
}
}