目录
242. 有效的字母异位词
349 两个数组的交集
202 快乐数
1 两数之和
242. 有效的字母异位词
看到题目的第一想法:将s串中的各个字符用map存放起来,key为字母,value为出现的次数,而后遍历t串中的字母,若字母在map中,则value的值减1,value为0时,remove此字母;最后判断map的size()是否为0即可。
看完代码随想录之后的想法:卡哥的方法,创建一个长度为26的数组,将s串中各字母的值-‘a’后作为下标,并且元素值++操作,而后遍历t串,同样将各字母的值-‘a’后作为下标,做--操作;最后遍历数组,若数组各元素全为0,则返回true,否则返回false。
代码实现:
- 我的思路
class Solution {
public boolean isAnagram(String s, String t) {
Map<Character, Integer> map = new HashMap<>();
if (s.length() != t.length()) {
return false;
}
//String.charAt(index)可以获得字符
//map.size()获取map的size map.remove(key)移除map中的元素
//将s中出现的每个字母放在map中,key记录字母,value记录字母出现的次数
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}
for (int j = 0; j < t.length(); j++) {
char ch = t.charAt(j);
//map.get(ch)有可能等于null,所以这里改用map.getOrDefault(ch,0)
if(map.getOrDefault(ch, 0) > 0) {
map.put(ch, map.get(ch) - 1);
//当字符的数量为0时,就将元素移除
if(map.getOrDefault(ch, 0) == 0) {
map.remove(ch);
}
} else {
return false;
}
}
if (map.size() == 0){
return true;
}
return false;
}
}
- 卡哥提供的方法
class Solution {
public boolean isAnagram(String s, String t) {
int[] arr = new int[26];
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
arr[c - 'a']++;
}
for (int j = 0; j < t.length(); j++) {
char ch = t.charAt(j);
arr[ch - 'a']--;
}
for (int a : arr) {
if (a != 0) {
return false;
}
}
return true;
}
}
实现过程中遇到哪些困难
- String.charAt()的用法不熟悉~
- map的相关操作,比如put,remove,getOrDefault,以及map.size()操作的不熟悉~
- 字符操作中,ch - 'a'得到的是int值,可以作为数组的下标;int数组在定义后,各元素初始值为0,可以进行++或--操作!
349 两个数组的交集
看到题目的第一想法+代码随想录提供的方法:依据题意,交集有重复的元素时,只需要输出一次,由此可以使用set集合,将数组一中的元素放入set1,而后遍历数组二中元素,若set1中有此元素,则将元素放入set2中,由于要返回数组,最后将set2转为数组即可~
代码实现:
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
//set.add添加元素,set.contains是否包含此元素
for (int i = 0; i < nums1.length; i++) {
set1.add(nums1[i]);
}
for (int j = 0; j < nums2.length; j++) {
//如果元素在set1出现过,则放在set2中
if(set1.contains(nums2[j])){
set2.add(nums2[j]);
}
}
//先求size而后再创建数组!
int size = (set2.size() == 0 ? 0 : set2.size());
int[] result = new int[size];
int i = 0;
//set如何进行遍历??
//迭代器和增强for循环
/*for (int value : set2) {
result[i++] = value;
}
//迭代器
Iterator<Integer> iterator = set2.iterator();
while (iterator.hasNext()){
result[i++] = iterator.next();
}
return result;*/
//set通过stream可以直接转换成数组
//return set2.stream().mapToInt(x -> x).toArray();
//set直接转成array时,得到的数组中元素类型是引用型,需进行转换
Integer[] integerArray = (set2.toArray(new Integer[size]));
for (int j = 0; j < integerArray.length; j++) {
result[j] = integerArray[j];
}
return result;
}
}
实现过程中遇到哪些困难:
- set中add,contains的使用
- set的遍历方法,增强for循环与迭代器遍历
//set如何进行遍历??
//迭代器和增强for循环
/*for (int value : set2) {
result[i++] = value;
}
//迭代器
Iterator<Integer> iterator = set2.iterator();
while (iterator.hasNext()){
result[i++] = iterator.next();
}
- set转array的方法:
- stream流:set2.stream().mapToInt(x -> x).toArray();
- 使用set的toArray方法:
- //set直接转成array时,得到的数组中元素类型是引用型integer,需要转换成int才满足题目需要
- Integer[] integerArray = set2.toArray(new Integer[size]);
for (int j = 0; j < integerArray.length; j++) {
result[j] = integerArray[j];
}
- 或者对set进行遍历,而后放入数组中~
202 快乐数
看到题目的第一想法:初看题目无思路,不清楚如果是多位数时,如何获得每一位的数值
看完代码随想录之后的想法:求各位数字的思路很明确,先用n % 10获得个位数值,而后n / 10使得数字位数减一;而后循环上述两步即得到每位数值!获取sum值后判断是否为1,若不为1就放入set中,而若set中此值已存在,则直接返回FALSE,因为此时已陷入循环;否则返回TRUE。
代码实现:
class Solution {
public boolean isHappy(int n) {
//初看时无思路,看了卡哥的方法,豁然开朗
//平方和有可能重复,这样就会陷入无限循环,需放入set中
int sum = getSum(n);
Set<Integer> set = new HashSet<>();
while(sum != 1){
//这么写会超时,忘记写set.add
if(set.contains(sum)) {
return false;
}
//下面的顺序不能放反,否则总会少数
set.add(sum);
sum = getSum(sum);
}
return true;
/*while(n != 1 && !set.contains(n)) {
set.add(n);
n = getSum(n);
}
return n == 1;*/
}
//获得正整数各位平方和
public int getSum(int n) {
int sum = 0;
while (n > 0) {
sum += (n % 10) * (n % 10);
//n /= 10可以让元素位数减一
n /= 10;
}
return sum;
}
}
实现过程中遇到哪些困难:
- 代码的顺序很重要,顺序混乱会导致缺值,如上面代码;
- 获取数据中的各位数字的方法,先求余数,而后除以10后,再求余数,不断循环即可~
1 两数之和
看到题目的第一想法:初看思路较乱,不知道如何处理[3,3],target=6的问题。
看完代码随想录之后的想法:卡哥的方法很清晰,遍历数组,查找target - nums[i]是否在map中,map的key为元素,value为具体角标,若存在则返回角标,并放入结果数组中,否则就将元素及角标放入map中。
代码实现:
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
if (nums == null || nums.length < 2) {
return result;
}
//key是元素值,value是元素下标
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int temp = target - nums[i];
//遍历元素,查找与temp相等的key
if (map.containsKey(temp)) {
result[1] = i;
result[0] = map.get(temp);
break;
}
map.put(nums[i], i);
}
return result;
}
}
实现过程中遇到哪些困难:
- 代码是否可以处理[3,3],target=6的问题
- 可以,第一个3时,map中不存在,而后放入map,第二个3时,即可查到之前放入的3了
今日收获,记录一下自己的学习时长
- 算法处理约3h,博客编写约2h
- 熟悉了map与set的基本使用,其基本用法,还要多家了解~
- 贵在坚持,加油!