#算法#哈希表#leetcode#两数之和
继续今天的练习记录。
目前没有day5的记录,因为我们的计划是每周日休息,但是后面我还是想把这一天补上来,作为前面一周练习的总结,尽量细致记录出错的地方和原因,查缺补漏吧。
今天练习的是哈希表相关的题目,哈希表经常用到,所以对哈希表比较熟悉,而目前算法练习的主要还是利用哈希表的元素唯一这个特性。如果对哈希表还不是很熟悉,可以先学习相关的内容,并不难。
242.有效的字母异位词
题目链接:242. 有效的字母异位词 - 力扣(LeetCode)给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。
这道题感觉解法很多,我这里用了两种方法。
第一种思路就是把字符串转成字符数组,然后sort,这样如果每一个指针下字符都相同,那就是字母异位词。
第二种就是利用数组,因为单词包含的字符有限,最多26个不同的字母,所以创建数组,通过字符和‘a’运算得到对应的下标,即每个字符对应数组的一个下标,先遍历记录s,数组元素值+1,遍历t,数组元素值-1,如果最终数组值都是0,那就是字母异位词,否则不是。
具体代码:
public boolean isAnagram(String s, String t) {
if(null == s || null == t) {
return false;
}
if(s.length() != t.length()) {
return false;
}
//解法1 先排序,再同个index判断
// char[] ss = s.toCharArray();
// Arrays.sort(ss);
// char[] tt = t.toCharArray();
// Arrays.sort(tt);
// for (int i = 0; i < s.length(); i++) {
// if(ss[i] != tt[i]) {
// return false;
// }
// }
// return true;
//解法2 同数组记录,因为单词包含的字母只有26个,可穷举
int[] container = new int[26];
char[] ss = s.toCharArray();
for(char c1 : ss) {
container[c1 -'a']++;
}
char[] tt = t.toCharArray();
for(char c2: tt) {
container[c2 - 'a']--;
}
for(int i = 0; i < 26; i++) {
if(container[i] != 0) {
return false;
}
}
return true;
}
349. 两个数组的交集
题目链接:349. 两个数组的交集 - 力扣(LeetCode)给定两个数组 nums1 和 nums2 ,返回 它们的 交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
唯一,不考虑结果顺序,出现这些条件,大部分情况下都是可以通过哈希表来解决。
思路:先将nums1的元素写入哈希表set1,然后遍历nums2数组,如果set1中包含nums2中的元素,将此元素记录到另一个哈希表中,注意这里为了方便,最好是记录到另一个哈希表resSet中,因为nums2中的元素也是可能重复的,这里可以做一次去重。然后将resSet转为数组即可。
具体代码:
public int[] intersection(int[] nums1, int[] nums2) {
int[] empty = new int[0];
if(null == nums1 || null == nums2) {
return empty;
}
//用set解决, Java的话就是 HashSet
Set<Integer> set = new HashSet<>();
Set<Integer> resSet = new HashSet<>();
for(int num1 : nums1) {
set.add(num1);
}
for(int num2 : nums2) {
if(set.contains(num2)) {
resSet.add(num2);
}
}
if(resSet.size() <= 0) {
return empty;
}
int[] res = new int[resSet.size()];
Iterator<Integer> it = resSet.iterator();
int i = 0;
while (it.hasNext()) {
res[i] = it.next();
i++;
}
return res;
}
202. 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
这道题我个人自己的想法是先计算sum,如果sum是1则返回,sum不是1,则递归。但是这里忽略了一个问题,这个递归很可能是无法退出的。这里还有另一个退出条件就是某一次的和sum之前已经出现过了,那这个数字一定不会是快乐数,所以这个时候就可以退出了。这道题还有一个点就是计算数组和,这个可以记一下,后面可以直接用。
有几个注意的点,sum要更新,n要更新,每次先记录上一次的和。
具体代码:
public boolean isHappy(int n) {
Set<Integer> res = new HashSet<>();
int sum = n;
while(1 != sum && !res.contains(sum)) {
res.add(sum);
sum = 0; //重新+的时候这里不能再加之前的sum,得置为0重新计算
while(n > 0) {
int num = n%10;
sum += num * num;
n = n/10;
}
if(1 == sum) {
return true;
}
n = sum;
}
return 1 == sum;
}
1. 两数之和
哈哈,终于到你了,梦开始的地方!
但是这道题没时间记录了,我明天会补充,很经典,但是并不难,很多刷leetcode的朋友应该都有提交记录了。
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
刚刚将这道题完成了,用两种方法,一种就是第一想法暴力解法,brute force solution,英文是这个么,前两天我看还是另一个词组,有英语比较好的朋友可以评论区说说看。一种是通过hashmap来存值和对应的下标。
暴力解法:两个for循环,将数组里面的数组两两相加,判断和是否是target。
哈希法:创建map,key用来存储数组元素,因为这道题不能使用重复的数字,所以这个特性也可以利用,value用来存储数组下标,遍历数组,如果map里面包含元素与遍历的当前数组元素的和为target,则找到目标值,返回对应的下标即可。
具体代码:
public int[] twoSum(int[] nums, int target) {
if(null == nums) {
return null;
}
// int length = nums.length;
// int[] res = new int[2];
//brute force solution
// for(int i = 0; i < length; i++) {
// for(int j = i+1; j < length; j++) {
// if(nums[i] + nums[j] == target) {
// res[0] = i;
// res[1] = j;
// }
// }
// }
// return res;
int length = nums.length;
int[] res = new int[2];
Map<Integer, Integer> map = new HashMap<>();
for(int i = 0; i < length; i++) {
int key = target - nums[i];
if(map.containsKey(key)) {
Integer v = map.get(key);
if(null != v) {
int vi = v;
res[0] = vi;
res[1] = i;
}
} else {
map.put(nums[i], i);
}
}
return res;
}
好了,这篇文章完结,继续下次的锻炼,继续加油!
有疑问或者认为写的有问题的朋友,欢迎留言交流!

194

被折叠的 条评论
为什么被折叠?



