算法训练day4 | php | 242.有效的字母异位词 , 349. 两个数组的交集 , 202. 快乐数, 1. 两数之和

一、力扣题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;
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值