代码随想录算法训练营第六天 | 242.有效的字母异位词349. 两个数组的交集202. 快乐数1. 两数之和
Posted 蔚尺丈八声
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码随想录算法训练营第六天 | 242.有效的字母异位词349. 两个数组的交集202. 快乐数1. 两数之和相关的知识,希望对你有一定的参考价值。
有效的字母异位词
class Solution
public boolean isAnagram(String s, String t)
/*
* 思路:
* 用数组当做统计26个字母出现次数的哈希表
*
* 参考:
* https://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#%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%89%
* 88%E6%9C%AC
*
*
* 定义一个数组叫做record.用来上记录字符串s里字符出现的次数。
* 需要把字符映射到数组也就是哈希表的索引下标上,因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。
* 再遍历字符串s的时候,只需要将s[i]-'a'所在的元素做+1操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。
* 这样就将字符串s中字符出现的次数,统计出来了。
* 那看一下如何检查字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
* 那么最后检查一下,record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。
* 最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
* 时间复杂度为O(n),空间上因为定义的是一个常量大小的辅助数组,所以空间复杂度为O(1)。
*
*/
int record[] = new int[26]; // 数组哈希表,记录每个字母的出现次数
// 记录字符串s中每个字母出现的次数
for (int i = 0; i < s.length(); i++)
int index = s.charAt(i) - 'a'; // 表示26个字母中的第几个字母
record[index]++;
// 如果字符串t含有某个字母,那么减一
for (int i = 0; i < t.length(); i++)
int index = t.charAt(i) - 'a';
record[index]--;
// record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
for (int i : record)
if (i != 0)
return false;
// record数组所有元素都为零0,说明字符串s和t是字母异位词
return true;
两个数组的交集
class Solution
public int[] intersection(int[] nums1, int[] nums2)
/*
* 思路:
* 使用哈希集合hashSet
*
* 参考:
* https://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#_349-%E4%B8%A4%E4%B8%AA%E6%95%B0%E7%BB%84%E7%9A%84%E4
* %BA%A4%E9%9B%86
*
* 注意题目特意说明:输出结果中的每个元素一定是唯一的,
* 也就是说输出的结果的去重的,同时可以不考虑输出结果的顺序。
*
* 如果用数组做哈希表,那么假设交集的数字只有5000,那么数组的下标得到4999,
* 造成存储空间的极大浪费。也即,如果哈希值比较少、特别分散、跨度非常大,
* 使用数组就造成空间的极大浪费。所以这个时候可以用哈希集合。
*
* 本题将一个数组变成哈希集合,然后遍历另一个数组与此哈希集合比较,
* 看是否出现过相同的元素。
*
*
*/
// 排除异常条件:数组不存在,或数组长度为0
if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0)
return new int[0];
Set<Integer> set1 = new HashSet<>(); // nums1数组的集合
Set<Integer> interSet = new HashSet<>(); // 交集
// 获得nums1数组的不重复元素
for (int i : nums1)
set1.add(i);
// 从nums2中找到与nums1数组相同的元素
for (int i : nums2)
if (set1.contains(i))
interSet.add(i);
// 集合变为int数组
// 注意hashset先变为stream,才能变为数组
return interSet.stream().mapToInt(x -> x).toArray();
快乐数
class Solution
public boolean isHappy(int n)
/*
* 思路:哈希集合
* 每次按快乐数公式计算的结果,一旦发现新的就存到哈希集合中,
* 如果发现哈希集合中已经存在此数,那么停止计算。(因为遇到
* 重复出现的数后,继续计算又会陷入循环当中)。
*
* 最后检查这个重复的数是否为1。
*
* 参考:
* https://programmercarl.com/0202.%E5%BF%AB%E4%B9%90%E6%95%B0.html
*
*/
Set<Integer> set = new HashSet<>();
// 一直计算快乐数,直到遇到重复的为止
// n!=1是因为题意说直到变成1,变成1就说明是快乐数满足条件可以退出循环了(1没必要再进入循环了)。
while (n != 1 && !set.contains(n))
set.add(n);
n = getNextNumber(n); // 按快乐数公式计算下一个
// 检查重复的数是否为1
return n == 1;
public int getNextNumber(int n)
/*
* 计算快乐数
*/
// 注意怎么取各个位的数字
int result = 0;
while (n != 0)
int tmp = n % 10; // 获得末位数
result += tmp * tmp;
n /= 10; // n的位数-1
return result;
两数之和
class Solution
public int[] twoSum(int[] nums, int target)
/*
* 思路:哈希表 key:数据元素,value:数组元素对应的下表
*
* 什么时候使用哈希法,当我们需要查询一个元素是否出现过,
* 或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
*
* 我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,
* 需要使用 key value结构来存放,key来存元素,value来存下标,
* 那么使用map正合适。
*
* 再来看一下使用数组和set来做哈希法的局限:
* 1、数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
* 2、set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,
* 不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x和y的下标。所以set也不能用。
* 此时就要选择另一种数据结构:map。
*
* 参考:
* https://programmercarl.com/0001.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.html#%E6
* %80%9D%E8%B7%AF
*
*/
// 存储满足题目条件的两个数的下标
int result[] = new int[2];
// 排除异常:如果数组为null或者数组长度为0
if (nums == null || nums.length == 0)
return result;
// map目的用来存放我们访问过的元素,因为遍历数组的时候,
// 需要记录我们之前遍历过哪些元素和对应的下标,
// 这样才能找到与当前元素相匹配的(也就是相加等于target)
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++)
// 检查两数之和的另一个数是否存在哈希表中
int tmp = target - nums[i];
if (map.containsKey(tmp))
result[1] = i;
result[0] = map.get(tmp); // 获得下标
break;
// map存元素和对应的下标
map.put(nums[i], i);
return result;
以上是关于代码随想录算法训练营第六天 | 242.有效的字母异位词349. 两个数组的交集202. 快乐数1. 两数之和的主要内容,如果未能解决你的问题,请参考以下文章
代码随想录算法训练营第五十六天 | 583. 两个字符串的删除操作72. 编辑距离编辑距离总结
代码随想录算法训练营第11天 | ● 20. 有效的括号 ● 1047. 删除字符串中的所有相邻重复项 ● 150. 逆波兰表达式求值
代码随想录算法训练营第14天 | ● 理论基础 ● 递归遍历 ● 迭代遍历 ● 统一迭代
代码随想录算法训练营第15天 | ● 层序遍历 10 ● 226.翻转二叉树 ● 101.对称二叉树 2