一、力扣题242. 有效的字母异位词
给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的字母异位词。
注意:若 s
和 t
中每个字符出现的次数都相同,则称 s
和 t
互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram" 输出: true
示例 2:
输入: s = "rat", t = "car" 输出: false
提示:
1 <= s.length, t.length <= 5 * 104
s
和t
仅包含小写字母
今天学习哈希表章节的内容,哈希表的运用场景是:当需要快速判断一个元素是否出现在集合里时,就考虑用哈希法。普通的数组遍历时间复杂度是O(n), 而哈希法是O(1)。
本题的解法是:定义一个数组res,先遍历字符串s,然后逐一把字母作为res的键名放入数组,当数组res中有该字母的键名时,对应值加一, 没有时,赋值为1。
然后再遍历字符串 t,当数组res中有对应字母的键名时,对应值减1,如果没有,说明 t 和 s 不是字母异位词,返回false。
最后遍历数组res,如果其中有元素的值不为0,说明t、s不是字母异位词,返回false,反之返回true。
function isAnagram($s, $t) {
$num = [];
for($i = 0; $i < strlen($s); $i++) {
if(!isset($num[$s[$i]])) {
$num[$s[$i]] = 1;
} else {
$num[$s[$i]]++;
}
}
for($i = 0; $i < strlen($t); $i++) {
if(!isset($num[$t[$i]])) {
return false;
}
$num[$t[$i]]--;
}
foreach($num as $key) {
if($key != 0) {
return false;
}
}
return true;
}
二、力扣题349. 两个数组的交集
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4] 解释:[4,9] 也是可通过的
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
本题的逻辑和上题类似,只是判断条件不太一样,上一道题将其中一个字符串先存入数组,再将另一个字符串与数组对比,最后通过数组来判断结果。而本题也是先把其中一个数组a用哈希法的方式(即hash数组的键名为存入数组a中元素的值)存入数组hash,需要注意的是存入时是去重的,值相同的元素只会存入一个。最后将hash数组与另一个数组对比,将相交的数组存入另一个数组result,存入时同样也是去重的。
但是其中用到的两个去重的方式不一样,存入hash数组的去重方式是重复赋值,存入result的去重方式是删除hash数组中已存入的对应元素。
function intersection($nums1, $nums2) {
if(!count($nums1) || !count($nums2)) {
return [];
}
$hash = $result = [];
foreach($nums1 as $key) {
if(!isset($hash[$key])) {
$hash[$key] = 1;
}
}
foreach($nums2 as $key) {
if(isset($hash[$key])) {
$result[] = $key;
unset($hash[$key]);
}
}
return $result;
}
三、力扣题202. 快乐数
编写一个算法来判断一个数 n
是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n
是 快乐数 就返回 true
;不是,则返回 false
。
示例 1:
输入:n = 19 输出:true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1
示例 2:
输入:n = 2 输出:false
提示:
1 <= n <= 231 - 1
这道题也是直接看题解的,本题破题的关键在于如果这个数不是快乐数,它就会无限循环,所以这个数会在循环计算的过程中重新变成原来的数,所以只要判断出循环过程中是否出现重复值,就可以了。
而判断重复值的方法,就用到了哈希法。用hash数组把每次计算完成的值存入,然后每次循环的时候都判断一次计算完成的值是否有在hash数组里,如果有,则返回false循环结束。
function isHappy($n) {
$hash = [];
while($n != 1) {
if(isset($hash[$n])) {
return false;
}
$hash[$n] = 1;
$n = $this->getSum($n);
echo " ";
echo $n;
echo " ";
}
return true;
}
function getSum($n) {
$sum = 0;
while($n > 0) {
$sum += ($n % 10)**2;
$n = intval($n / 10);
}
return $sum;
}
四、力扣题1. 两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6 输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6 输出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 只会存在一个有效答案
本题和以上几题的思路类似。破题关键在于找出什么场景下会在集合中寻找一个元素,本题要找两个和为目标值的元素,当拿到其中一个元素a时,如果存在另一个元素b对应,那这个元素b一定等于(目标值-元素a的值),故我们要在集合中寻找的就是元素b。
定义一个hash数组,再遍历数组nums,每遍历一个元素时,就判断hash数组中是否有与之对应的元素,没有的话就将该元素存入hash数组,存入的方式是键名为元素的值、键值为元素在nums数组中的索引下标。这样做的原因是键名为元素的值才能用哈希法达到更快的查询速度,而题目要求返回数组下标,所以也需要存入下标。
function twoSum($nums, $target) {
$hash = [];
$result = [];
for($i = 0; $i < count($nums); $i++) {
$n = $target - $nums[$i];
if(isset($hash[$n])) {
return [$i, $hash[$n]];
}
$hash[$nums[$i]] = $i;
}
}