代码随想录
[注:题目来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/minimum-size-subarray-sum]
目录
242.有效的字母异位词
349. 两个数组的交集
202. 快乐数
?1. 两数之和
?
今天是第一天做哈希表,不太会,不过四道题做下来也颇有收获。继续坚持!
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若?s 和 t?中每个字符出现的次数都相同,则称?s 和 t?互为字母异位词。
输入: s = "anagram", t = "nagaram"
输出: true
拿到这道题,由于还不知道如何使用哈希表,思路就是先把两个字符串转成数组,然后使用两个for循环解决。看了解析后,才发现哈希表真是yyds!
什么时候要用哈希表?
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
这里先创建一个26位的数组(一共26个小写字母),然后记录其中一个字符串中出现的字母(映射到哈希表,这里哈希表使用的是数组),最后遍历另一个字符串,也映射到哈希表。
/**
* 242. 有效的字母异位词
* @param s 两个字符串 s
* @param t t
* @return 判断 t 是否是 s 的字母异位词,若是返回true,否则返回false
*/
public static boolean isAnagram(String s, String t) {
// 输入: s = "anagram", t = "nagaram" 输出: true
int[] record = new int[26];
for (int i = 0; i < s.length(); i++) {
record[s.charAt(i) - 'a']++;//这里++
}
for (int i = 0; i < t.length(); i++) {
record[t.charAt(i) - 'a']--;//这里--可以简化下面的if语句
}
for (int j : record) {
if (j != 0) {
return false;
}
}
return true;
给定两个数组?nums1 ?和?nums2 ?,返回?它们的交集?。输出结果中的每个元素一定是?唯一?的。我们可以?不考虑输出结果的顺序?。
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
我发现我好像只会暴力解法......这里现在看来挺简单,就是使用两个Set作为哈希表,一个是对一个数组去重,一个是用来存放另一个数组和这个去重后的数组相交的元素。
/**
* 349. 两个数组的交集
* @param nums1 两个数组 nums1
* @param nums2 nums2
* @return 返回 它们的交集
*/
public static int[] intersection(int[] nums1, int[] nums2) {
// 输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]
//用Set做哈希表
// Set<Integer> sets = new HashSet<>();
// Set<Integer> intersection1 = new HashSet<>();
// for (int j : nums1) {
// sets.add(j);
// }
// for (int i : nums2) {
// if(sets.contains(i)){
// intersection1.add(i);
// }
// }
// return intersection1.stream().mapToInt(x -> x).toArray();
//下面是用数组做哈希表
//1 <= nums1.length, nums2.length <= 1000,故数组长度设置大一点就行
int[] record = new int[1001];
Set<Integer> resSet = new HashSet<>();
for (int i : nums1) {
record[i] = 1;
}
for (int i : nums2) {
if (record[i] == 1){
resSet.add(i);
}
}
return resSet.stream().mapToInt(x -> x).toArray();//这里这个方法没见过
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」?定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。 如果这个过程 结果为?1,那么这个数就是快乐数。 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
刚拿到这道题挺懵逼的,不会做,看了一点解析准备自己写,发现求和也没写出来,我是真的菜啊,这必须得二刷了。
这道题核心思路还是判断一个元素是否出现在集合里,循环结束的条件就是循环是否为1.
/**
* 202. 快乐数
* @param n 一个正整数
* @return 如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
*/
public static boolean isHappy(int n) {
//输入:n = 19 输出:true
Set<Integer> sumArray = new HashSet<>();
while (n > 0){
n = getSum(n);//这里有点绕
if (sumArray.contains(n)){
return n == 1;
}else {
sumArray.add(n);
}
}
return false;
}
public static int getSum(int n){
int sum = 0;
int temp;
while (n > 0){
temp = n % 10;
sum += temp * temp;
n /= 10;
}
return sum;
给定一个整数数组?nums ?和一个整数目标值?target ,请你在该数组中找出?和为目标值?target ? 的那?两个?整数,并返回它们的数组下标。
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
没啥好说的,梦结束的地方。
核心还是判断一个元素是否出现在集合里,只不过是稍微拐了一点弯,我是真的笨b一个。
这里选用Map作为哈希表是由于:这里查找的元素和最后要输出的不是同一个东西,而且由于Set和Map都是无序的,这里返回的是查找值的索引,问为什么不用数组作为哈希表,首先因为数组是根据索引读取元素,与这里的需求找值返回索引不一样,其次这里用数组那纯纯的就是暴力。
?
/**
* 1. 两数之和
* @param nums 一个整数数组 nums
* @param target 个整数目标值 target
* @return 在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
*/
public static int[] twoSum(int[] nums, int target) {
//输入:nums = [2,7,11,15], target = 9 输出:[0,1]
int[] res = new int[2];
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (map.containsKey(target - nums[i])){
res[0] = i;
res[1] = map.get(target - nums[i]);
}else {
map.put(nums[i], i);
}
}
return res;
|