242. 有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意: 若 s 和 t **中每个字符出现的次数都相同,则称 s 和 t **互为字母异位词。
思路
创建一个大小为26的整数数组,每一位代表一个字母,从0 ~ 25代表字母a~z;
首先遍历字符串s,每个字母出现一次,对应数组位置的数加一;
然后遍历字符串s,每个字母出现一次,对应数组位置的数减一;
最后重新遍历数组,如果某个位置的数字不为0,那么则说明两个字符串某个字幕出现的次数不一样,因此不是字母异位词。
代码实现
class Solution {
public boolean isAnagram(String s, String t) {
int[] dic = new int[26];
for (int i = 0; i < s.length(); ++i) {
dic[s.charAt(i) - 'a']++;
}
for (int i = 0; i < t.length(); ++i) {
dic[t.charAt(i) - 'a']--;
}
for (int i = 0; i < 26; ++i) {
if (dic[i] != 0) {
return false;
}
}
return true;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
349. 两个数组的交集
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
思路
首先遍历一遍nums1数组,把出现的数字加入set集合;
然后遍历nums2数字,并检查nums2数组中每个数字是否在set集合中出现,出现的话加入结果集,没有继续检查下一个。
代码实现
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set = new HashSet<>();
Set<Integer> resSet = new HashSet<>();
for (int i = 0; i < nums1.length; ++i) {
set.add(nums1[i]);
}
for (int i = 0; i < nums2.length; ++i) {
if (set.contains(nums2[i])){
resSet.add(nums2[i]);
}
}
int i = 0;
int[] arr = new int[resSet.size()];
for (int number : resSet) {
arr[i++] = number;
}
return arr;
}
}
- 时间复杂度:O(n + m)
- 空间复杂度:O(n)
202. 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
思路
首先,我们要知道如何判断是否是无限循环始终变不到1。
可以使用set集合来辅助,如果一个数会无限循环,那么他就会反复出现;基于这个特性,每次一个数出现我们就判断其是否存在于set集合,如果存在则代表这个数会无限循环,可以直接return false,如果不存在就加入集合。通过这种方法,我们就可以排除出那些无法变为1的数。
当出现n == 1或者 set.contains(n)两种中任一种的情况时,我们就可以跳出循环,判断n是否为1,即return n == 1。这样就能得到最终结果。
代码实现
class Solution {
public boolean isHappy(int n) {
Set<Integer> set = new HashSet<>();
while (n != 1 && !set.contains(n)) {
set.add(n);
n = getNum(n);
}
return n == 1;
}
// 通过这个方法将一个数替换为它每个位置上的数字的平方和
private int getNum(int num) {
int sum = 0;
while (num != 0) {
int temp = num % 10;
sum += temp * temp;
num = num / 10;
}
return sum;
}
}
- 时间复杂度:O(log n)
- 空间复杂度:O(log n)
1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
思路-使用map来解决
要使用map, 我们首先要明确两点:
- map用来做什么
- map中key和value分别用来表示什么
本题中,使用map的目的是用于存储数组元素与其对应的数组下标,因为我们要返回的是下标,因此value代表下标,key代表数组中的元素。
明确了这两点以后我们就可以开始我们的解题思路了;
首先我们遍历数组,同时检查map中是否存在一个key,这个key与当前数组遍历元素的和为target。如果map中存在这个key,那么我们就找到了这个唯一解。因为本体必定有且只有一个唯一解,因此不用考虑不存在答案以及复数答案的情况。
过程如下:
注意:
以上的操作都需要在一次遍历中完成,如果我下图代码就犯了一个错误:
假设题目为 {3, 2, 4}, target = 6;
在我第二遍循环带第 0 个数字的时候,因为map中已经有了 key = 3, value = 0 的键值对,因此他会直接返回 结果 {0, 0}; 而题目是不允许一个数字用两次的,因此这样是无法AC的。
代码实现
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; ++i) {
int diff = target - nums[i];
if (map.containsKey(diff)) {
return new int[] {map.get(diff), i};
}
map.put(nums[i], i);
}
return new int[]{};
}
}
- 时间复杂度: O(n)
- 空间复杂度: O(n)