242.有效的字母异位词
思路
判断两个字符串每个字符出现的次数是否都相同 --> 存储这两个字符串各个字母出现的次数并判断 --> 一个字符串存,一个字符串减
重点:
- 需要能快速获取指定字符的数量 --> 哈希表
- 如果最后所有字符的数量总和为 0,则两字符串为异位词
解题方法
依照哈希表的原理,可以使用数组来实现
索引通过字母ascii码相对 a
的位置来确定
复杂度
-
时间复杂度:
O ( n ) O(n) O(n) -
空间复杂度:
O ( 1 ) O(1) O(1)
Code
Java
class Solution {
public boolean isAnagram(String s, String t) {
// 哈希表存储s字段各个字母的个数,然后t字段删减
// 根据哈希表的原理,用数组存字母个数,用字母ascii码与a的相对位置作为数组索引
int[] record = new int[26];
// s 字符串往 record 新增
for (int i = 0; i < s.length(); i++) {
record[s.charAt(i) - 'a']++;
}
// t 字符串往 record 删减
for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;
}
// 遍历 record,判断总和是否为 0,为 0 则符合字母异位词
for (int sum: record) {
if (sum != 0) {
return false;
}
}
return true;
}
}
349. 两个数组的交集
思路
输入数组数据范围、个数可控,可以使用基于数组的哈希表
解题方法
- 构建两个基于数组的哈希表,存储输入的数组都有什么数
- 将都有的数值放到列表中(长度不定),然后转成数组输出
复杂度
-
时间复杂度:
O ( n ) O(n) O(n) -
空间复杂度:
O ( 1 ) O(1) O(1)
Code
Java
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
// 输入数组数据范围、个数可控,可以使用基于数组的哈希表
// 索引为输入数组的数值
int[] record1 = new int[1001];
int[] record2 = new int[1001];
List<Integer> result = new ArrayList<>();
// 分别记录各自数组都有什么数
for (int num: nums1) {
record1[num]++;
}
for (int num: nums2) {
record2[num]++;
}
// 将有数的记录到result中,转换为数组输出
for (int i = 0; i < record1.length; i++) {
if (record1[i] != 0 && record2[i] != 0) {
result.add(i);
}
}
return result.stream().mapToInt(x -> x).toArray();
}
}
202. 快乐数
思路
- 判断是否循环则需要记录历史数据,且要能 O(1) 时间内找到,而且这历史记录的数据量不清楚 --> 哈希表
- 计算逻辑 --> 取给定数值的各个位数上的值
解题方法
HashSet
取模
复杂度
-
时间复杂度:
O ( l o g n ) O(logn) O(logn) -
空间复杂度:
O ( l o g n ) O(logn) O(logn)
Code
Java
class Solution {
public boolean isHappy(int n) {
// 判断是否循环 --> 判断sum是否重复 --> 哈希表
Set<Integer> record = new HashSet<>();
while(n != 1 && !record.contains(n)) {
record.add(n);
n = generateHappyNum(n);
}
return n == 1;
}
private int generateHappyNum(int n) {
int result = 0;
// 通过循环取模,实现按位数取值
while(n > 0) {
int temp = n % 10;
// 平方和
result += temp * temp;
n = n / 10;
}
return result;
}
}
1. 两数之和
思路
遍历输入的数组,对每个数,都去哈希表查一下有没有所需的数,如果没有,则把自己存进去,如果有,则返回
- 哈希表需要能存储键值对 --> 值,索引
- 能不受限存
所以使用 HashMap
复杂度
-
时间复杂度:
O ( n ) O(n) O(n) -
空间复杂度:
O ( n ) O(n) O(n)
Code
Java
class Solution {
public int[] twoSum(int[] nums, int target) {
// 遍历输入的数组,对每个数,都来 record 查一下有没有所需的数,如果没有,则把自己存进去,如果有,则返回
// <数值,索引>
Map<Integer, Integer> record = new HashMap<>();
for(int i = 0; i < nums.length; i++) {
int need = target - nums[i];
Integer needIndex = record.get(need);
if (needIndex != null) {
return new int[]{i, needIndex};
}
record.put(nums[i], i);
}
return new int[0];
}
}