代码随想录算法训练营第六天|242.有效的字母异位词、349两个数组的交集、202快乐数、1.两数之和

有效的字母异位词

leetcode242

直观思路

        用数组的思想来做,字母异位词意味着两个字符串数组中,所包含的字符及其出现次数是相同的,这就意味着字符串的长度相同以及若排序后各位置应该都相同(不考虑对单个字符进行次数估计的原因在于不知道存在多少个字符)。

class Solution {
public:
    bool isAnagram(string s, string t) {
        if(s.length() != t.length()){
            return false;
        }//如果s和t长度不同,返回false
        sort(s.begin(),s.end());
        sort(t.begin(),t.end());//对s和t进行排序
        return s == t;//返回s和t相等的情况
    }
};

        算法的时间复杂度为O(nlogn)(sort快排O(nlogn),比较为O(n),综上为O(nlogn)),空间复杂度为O(1)。

简易哈希表

        考虑一个单词由小于等于26个字母组成,创建一个全为0的数组ivect,以a下标索引为0,b下标索引为1...以此为例。针对字符串s,遍历s,对s中出现的每个字母更新数组(ivect[i]++),之后遍历t,对t中出现的每个字母(ivect[i]--),若最后数组全为0,则为字母异位词,返回true,否则返回false。

        

class Solution {
public:
    bool isAnagram(string s, string t) {
        if(s.length()!=t.length())//首先判断长度,若长度不同,直接返回false
            return false;
        vector<int> ivect(26,0);//创建长度为26的数组ivect,简易的哈希表
        for(int i = 0;i<s.length();i++){//对字符串s遍历,ivect相应位置增
            ivect[s[i] - 'a']++;//这里使用利用ascii码的相对位置,'a'-'a' = 0,以此类推
        }
        for(int j = 0;j<s.length();j++){//对字符串t遍历,ivect相应位置减
            ivect[t[j] - 'a']--;
        }
        for(int i = 0;i < 26;i++){//若最后ivect不全为0返回false,否则返回true
            if(ivect[i]!=0){
                return false;
            }
        }
        return true;
    }
};

算法的空间复杂度为O(1),时间复杂度为O(n)。

两个数组的交集

        考虑使用哈希表,将两个数组分别存入哈希表set1、set2,这种方式可以保证获得唯一的数组元素,之后判断哈希表中是否有元素相同,若存在相同元素,将其加入数组ivect,之后返回ivect。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> ivect = {};
        unordered_set<int> set1, set2;
        for(auto &num:nums1){//将nums1中元素存入哈希表1
            set1.insert(num);
        }
        for(auto &num:nums2){//将nums2中元素存入哈希表2
            set2.insert(num);
        }
        if(set1.size()>set2.size()){//判断哈希表1和哈希表2的长度,选取较短长度的哈希表
            swap(set1,set2);
        }
        for(auto&num:set1){//判断较长哈希表中是否存在较短哈希表元素,若存在,在ivect中加入
            if(set2.count(num))
                ivect.push_back(num);
        }

        return ivect;
    }
};

设两个数组长度为n和m,算法的时间复杂度为O(n+m),算法的空间复杂度为O(n) 

快乐数

        这里需要强调无限循环,意味着若非快乐数,则在运行过程中,会出现重复数值,这时可以考虑使用哈希表。

class Solution {
public:
    int getsum(int n){//将一个数替换为它每个位置上的数字的平方和
        int sum = 0;
        while(n){
            sum += (n%10) * (n%10);//取出个位数,将个位数求平方
            n = n/10;//将该数/10,十位变个位 以此类推
        }
        return sum;//返回一次计算结果
    }
    bool isHappy(int n) {
        int sum = 0;
        unordered_set<int> set;//创建哈希表
        sum = getsum(n);//计算结果
        while(1){
            if(sum == 1){
                return true;//当符合sum == 1时,return True
            }
            if(set.count(sum)){//否则若原表中含这个数,则return false
                return false;
            }
            set.insert(sum);//将这个数加入哈希表中
            sum = getsum(sum);//重新计算一次,并进入循环
        }
    }
};

两数之和

暴力解法

        遍历两次数组,找到两数和为target的下标索引并返回。算法时间复杂度O(n^2),空间复杂度O(1)。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int>ivect = {};
        for(int i = 0; i <nums.size();i++){
            int x = target - nums[i];//计算与目标的差距,在遍历中寻找
            for(int j = 0; j < nums.size();j++){
                    if(nums[j] == x and i != j){
                        ivect.push_back(i);
                        ivect.push_back(j);
                        return ivect;
                    }
            }
        }
        return ivect;
    }
};

哈希表

        这里考虑题目是当已经有一个元素,要去寻找是否存在另一个元素也在这个数组中,实现这两个元素相加为target,考虑这一要求,我们需要去查询一个元素是否在一个集合中,考虑使用哈希表。

        对数组中元素遍历的过程中,计算元素与target之间的差距x,在哈希表中查找x,若存在,返回其索引和当前遍历下标;若不存在,将当前元素与其在数组中的下表索引存入哈希表中,哈希表用来存放我们已经遍历过的元素及其下标索引,关键词为元素,键值value为其索引。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::unordered_map<int, int> numMap; // 创建哈希表
    for (int i = 0; i < nums.size(); ++i) {
        int x = target - nums[i]; // 计算目标值
        if (numMap.count(x)) {
            // 如果找到了目标值,返回结果
            return {numMap[x], i};
        }
        // 如果没找到,将当前元素和它的下标加入哈希表
        numMap[nums[i]] = i;
    }
    return {}; // 如果没有找到,返回空数组
    }
};

算法的时间复杂度为O(n),空间复杂度O(n),代价,用空间换时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值