代码随想录第六天| 242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和
什么时候想到用哈希法,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
第一题 242.有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
ψ(`∇´)ψ 我的思路
- 这是我拿到题一开始的思路,两个字符串装到俩个map中,再进行比较
package hash;
import java.util.HashMap;
import java.util.Set;
class IsAnagram {
public static boolean isAnagram(String s, String t) {
char c;
HashMap<Character, Integer> smap = new HashMap<>();
int len = s.length();//字符串的长度
for (int i = 0; i < len; i++) {
c = s.charAt(i);//挨个取出s字符串中的每一个字符
if(smap.containsKey(c)){//如果key中已有c
smap.put(c,smap.get(c)+1);//把c中原来的值+1再赋给c
} else {
smap.put(c,1);//如果key中没有c,添加c并赋值1
}
}
HashMap<Character, Integer> tmap = new HashMap<>();
for (int i = 0; i < len; i++) {
c = t.charAt(i);//挨个取出t字符串中的每一个字符
if(tmap.containsKey(c)){//如果key中已有c
tmap.put(c,tmap.get(c)+1);//把c中原来的值+1再赋给c
} else {
tmap.put(c,1);//如果key中没有c,添加c并赋值1
}
}
if(smap==tmap){
return true;
}else {
return false;
}
}
public static void main(String[] args) {
String s = "anagram";
String t = "nagaram";
System.out.println(isAnagram(s, t));
}
}
-
后来debug发现==判断的是两个map的地址
-
改进后的思路:只用一个map,第一个字符串存,第二个字符串取
public static boolean isAnagram(String s, String t) {
if(s.length()!=t.length()){
return false;//长度都不等,你还比个什么呢,返回吧
}
char c;
HashMap<Character, Integer> map = new HashMap<>();
int len = s.length();//字符串的长度
for (int i = 0; i < len; i++) {
c = s.charAt(i);//挨个取出s字符串中的每一个字符
if(map.containsKey(c)){//如果key中已有c
map.put(c,map.get(c)+1);//把c中原来的值+1再赋给c
} else {
map.put(c,1);//如果key中没有c,添加c并赋值1
}
}
for (int i = 0; i < len; i++) {
c = t.charAt(i);//挨个取出t字符串中的每一个字符
if(map.containsKey(c)){//如果key中已有c
map.put(c,map.get(c)-1);//把c中原来的值-1再赋给c
if (map.get(c)==0){
map.remove(c);//当c的值减到0的时候移除c
}
} else {
return false;//如果key中没有c,直接返回false
}
}
if(map.isEmpty()){
return true;
}else {
return false;
}
}
- 通过之后我在写博客的时候发现只要将第一种方法的==换成equal就也可以通过😅
- 看了官方题解,是字符串转成char[]后排序比较,就😶
第二题349. 两个数组的交集
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
ψ(`∇´)ψ 我的思路
- 先把两个数组存到set里保证他们不重复,把其中一个set转成数组,不然没法遍历,第一遍遍历数组确定交集元素的数量,这样才能创建数组,第二遍遍历数组把交集元素存到数组中
package hash;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class Intersection {
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set1 = new TreeSet<>();
for (int i = 0; i < nums1.length; i++) {
set1.add(nums1[i]);//把数组中的元素装到set里,确保每个元素只出现一次
}
Object[] arr1 = set1.toArray();//
Set<Integer> set2 = new HashSet<>();
for (int i = 0; i < nums2.length; i++) {
set2.add(nums2[i]);//把数组中的元素装到set里,确保每个元素只出现一次
}
int j = 0;
for (int i = 0; i < arr1.length; i++) {
if(set2.contains(arr1[i])){
j++;//这次遍历是为了得到数组的长度
}
}
int[] res = new int[j];
j = 0;
for (int i = 0; i < arr1.length; i++) {
if(set2.contains(arr1[i])){
res[j++] = (int) arr1[i];//交集元素存入数组
}
}
return res;
}
}
- 下面是代码随想录中的解法
import java.util.HashSet;
import java.util.Set;
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<>();
//遍历数组1
for (int i : nums1) {
set1.add(i);
}
//遍历数组2的过程中判断哈希表中是否存在该元素
for (int i : nums2) {
if (set1.contains(i)) {
resSet.add(i);
}
}
//将结果几何转为数组
return resSet.stream().mapToInt(x -> x).toArray();
}
}
- 我觉得这个解法挺好,把一个数组转成set,留了一个用来遍历,交集元素存入新set,最后set转array,这算是对我的解法的改进
第三题202. 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
ψ(`∇´)ψ 我的思路
- 这题复杂是复杂了点,但顺着思路写还行,我目前写的程序可以把快乐数判断出来,返回true,不是快乐数的会一直循环所以超时的就不是快乐数🤪
- 我现在可以把任何一个整形判断出来是不是快乐数但是却没法通过leetcode😅,因为我找不到结束循环的条件
package hash;
public class IsHappy {
public static boolean isHappy(int n) {
int sum = 0;
int[] ints = intToInts(n);
while (sum!=1){
for (int i = 0; i < ints.length; i++) {
sum +=ints[i]*ints[i];
}
if(sum==1){
return true;
}
ints = intToInts(sum);
sum = 0;
}
return true;
}
private static int[] intToInts(int n){
// 先写一个方法把整数拆成数组
int i = 1;
int x = n;
while (x/10!=0){
x = x/10;
i++;//确定整数的位数
}
int[] ints = new int[i];
for (int j = 0; j < i; j++) {
ints[j] = n%10;
n = n/10;
}
return ints;
}
}
- 我回去又把题目看了一遍,
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
- 这就好办了,我把每一次计算出的sum记录下来,存在set中,sum在set中重复的时间点就是我该跳出循环的位置。
package hash;
import java.util.HashSet;
import java.util.Set;
public class IsHappy {
public static boolean isHappy(int n) {
int sum = 0;
Set<Integer> set = new HashSet<>();
int[] ints = intToInts(n);
while (sum!=1){
for (int i = 0; i < ints.length; i++) {
sum +=ints[i]*ints[i];
}
if(!set.contains(sum)){//如果set中没有出现过sum
set.add(sum);//把sum都加入到set中
} else {//如果set中已经有sum,说明已经开始循环
return false;
}
if(sum==1){
return true;
}
ints = intToInts(sum);
sum = 0;
}
return true;
}
private static int[] intToInts(int n){
// 先写一个方法把整数拆成数组
int i = 1;
int x = n;
while (x/10!=0){
x = x/10;
i++;//确定整数的位数
}
int[] ints = new int[i];
for (int j = 0; j < i; j++) {
ints[j] = n%10;
n = n/10;
}
return ints;
}
}
第四题1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
- 这这这,这不就是梦开始的地方嘛,这就是我注册leetcode那天写的题,把当时的代码粘下
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length ; j++) {
if((nums[i]+nums[j])==target){
result[0] = i;
result[1] = j;
}
}
}
return result;
}
}
- 就是暴力!!!
ψ(`∇´)ψ 我的思路
- 其实我想半天也没有想到用哈希表做题的思路,然后我就看了代码随想录的思路,真的是妙蛙种子吃了妙脆角妙到家啦hhh
package hash;
import java.util.HashMap;
import java.util.Map;
public class TwoSum {
public static int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
int[] res = new int[2];
for (int i = 0; i < nums.length; i++) {
//将数组的元素作为key,数组下标作为value存入map
if(map.containsKey(target-nums[i])){//如果map中已经加入了要寻找的值
res[0] = map.get(target-nums[i]);
res[1] = i;//当前值的下标
}
map.put(nums[i],i);
}
return res;
}
}
- 我有想过把数组装到哈希表中,但是思维固化还是想着要以下标为key,没想到下标是value
总结
-
感觉哈希表是比链表简单的,可能也是因为今天的四题都是简单题
-
没啥问题,期待明天的中等题
-
真的一天中第二快乐的事就是刷题了
-
蔫儿蔫儿的今天,真的晚上不能再喝咖啡了,身体睡着了,灵魂还清醒
分类:
leetcode
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人