所用代码 java
有效的字母异位词 LeetCode 242
题目链接:有效的字母异位词 LeetCode 242 - 简单
思路
1、直接使用hashmap来存:若字符串A=[aabc],字符串B=[baac],我们先把a的所有字母存在一个哈希表里面,key存元素,value就存出现的次数。然后再来一个for循环用于消除value的值,若value=0了就删除该值,不存在key就返回false,最后再看hash是不是为空,空就返回true。
public boolean isAnagram(String s, String t) {
HashMap<Character, Integer> hash = new HashMap<>();
// 存s的值,并记录出现了几次
for (char c : s.toCharArray()){
if (hash.containsKey(c)) {
hash.put(c, hash.get(c) + 1);
} else {
hash.put(c, 1);
}
}
// 消除该值出现的次数
for (char c : t.toCharArray()){
// 不存在就直接返回false
if (hash.get(c) == null) {
return false;
} else if (hash.get(c) > 1) {
hash.put(c, hash.get(c) - 1);
} else {
// 只出现一次就删除
hash.remove(c);
}
}
// 空就代表哈希表里边的数删完了
return hash.isEmpty();
}
2、利用数组作为哈希表: 由于该题数据比较小,可以定义一个长度为26的数组res(a-z共26个字母,a从下标0开始,我们使用 s.charAt(i) - 'a' 26个字母就刚好存在对应的位置),s中存每一个字母出现的次数,t中每个字母出现一次res中所记录该字母的值就-1,最后再判断该数组是不是所有值都为零,是就返回true。
public boolean isAnagram(String s, String t) {
int[] res = new int[26];
// 取s中每一个字母存入对应位置,并判断出现了几次
for (char c : s.toCharArray()){
res[c - 'a']++;
}
// 取t中每一个字母判断出现没,出现一次就减1
for (char c : t.toCharArray()){
res[c - 'a']--;
}
// 判断res是不是每一个值都为0,不是就返回false
for (int i : res){
if (i != 0){
return false;
}
}
return true;
}
总结
经自己测试,方法二比方法一快得多,因为他并没有那么多哈希运算与判断逻辑。所以我们在数据量小的时候使用数组作为哈希表的话效率是更高的
两个数组的交集 LeetCode 349
题目链接:两个数组的交集 LeetCode 349 - 简单
思路
首先想到的是用set,由于我们的数据是要去重的,所以用set是非常好的选择,我们可以直接遍历两个数组,然后用一个set来存数组,一个set存相同的值,这样即完成的找相同值,也完成的去重。
public int[] intersection(int[] nums1, int[] nums2) {
Set<Integer> set = new HashSet<>();
Set<Integer> res = new HashSet<>();
//set负责存nums1的所有数
for (int i = 0; i < nums1.length; i++) {
set.add(nums1[i]);
}
//res负责存两个数组去重后的交集
for (int i = 0; i < nums2.length; i++) {
if (set.contains(nums2[i])){
res.add(nums2[i]);
}
}
// 将res转为int[] 数组
int[] resNum = new int[res.size()];
int count = 0;
for (Integer num : res){
resNum[count] = num;
count++;
}
return resNum;
// 将res结果转换为int型的数组
// return res.stream().mapToInt(x -> x).toArray();
// return set.stream().mapToInt(Integer::intValue).toArray();
}
总结
本题我想出方法是非常容易的,难点在于如何将一个set型的数据转换为一个int型的数组,一般的话可以直接用for循环来遍历set,然后复制给一个新的数组,另外一个就是使用stream流来操作(这个不太会)。另外这个题由于数据比较小,数字不大于1000,也可以使用数组来解决。
主要代码:
int[] hash = new int[1001];
Set<Integer> set = new HashSet<>();
for (int i = 0; i < nums1.length; i++) {
hash[nums1[i]] = 1;
}
for (int i = 0; i < nums2.length; i++) {
if (hash[nums2[i]] == 1){
set.add(nums2[i]);
}
}
快乐数 LeetCode 202
题目链接:快乐数 LeetCode 202 - 简单
思路
本题无思路,只大概知道循环求数的平方,但是不知道该怎么做,看的解答
public boolean isHappy(int n) {
Set<Integer> set = new HashSet<>();
//退出循环有两种情况,一是n=1,二是set里面的值有重复了(n=1也有可能只有一个1)
while (n != 1 && !set.contains(n)){
set.add(n);
n = getNextNum(n);
// System.out.println(sum);
}
return n == 1;
}
public int getNextNum(int n){
int res = 0;
while (n > 0){
int num = n % 10;
res += num * num;
n /= 10;
}
return res;
}
总结
一看看去确实不太清楚怎么做,只知道如何求平方,但是怎么根据此来解题不太清楚。看了解析才知道对于这种求重复的数我们最好使用set来解答,下次遇到这种类型的一定要第一时间想用set,然后再去一步一步分享解答。
两数之和 LeetCode
题目链接:两数之和 LeetCode - 简单
思路
1、暴力: 两层for循环搞定
2、hashmap: 我们遍历这个数组,并依次把数据存入hashmap里面
public int[] twoSum(int[] nums, int target) {
int[] res = new int[2];
if (nums == null || nums.length == 0){
return res;
}
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int temp = target-nums[i];
if (map.containsKey(nums[i])){
res[0] = i;
res[1] = map.get(nums[i]);
break;
}
// 存放操作必须放在第二步,否则(3,3) tar=6会直接返回(0,0)
map.put(temp,i);
}
return res;
}
总结
两数之后,梦开始的地方!LeetCode有一评论:有人相爱,有人夜里开车看海,有人leetcode第一题都做不出来。我刚刷题就是第一题都不会做的人,但是今天做这题用hash有些细节把握也不是很好,总是会出一些错误,但是我相信60天后一定会蜕变!