代码随想录训练营day06打卡

有效的字母异位词

242. 有效的字母异位词

哈希表的应用:其实本题就是比较两个字符串中每个字母出现的次数是否相等,我们使用一个hash[26]代表a字母到z字母的出现次数,由于a到z的ASCII码是连续的,因此用该字符-'a'的值对应了0-25,分别是数组hash[26]的对应下标。


        int hash[26] = { 0 };
        for (int i=0;i<s.size(); i++)
        {
            hash[s[i] - 'a']++;
        }

然后为了比较字符串s和t,我们先将s的每个字符存入hash[26]中,然后再遍历t的每一个字符,每遍历到一次,就将该字符的频率-1,最后再遍历hash[26],如果全部值都为0,则完全遍历,输出ture,如果遍历过程有一个不为0,说明不是字母异位词,因此输出false。完整代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int hash[26] = { 0 };
        for (int i=0;i<s.size(); i++)
        {
            hash[s[i] - 'a']++;
        }
        for (int i = 0; i < t.size(); i++)
        {
            hash[t[i] - 'a']--;
        }
        for (int i = 0; i < 26; i++)
        {
            if (hash[i]) return false;
        }
        return true;
    }
};

两个数组的交集

349. 两个数组的交集

根据题目的输出我们可以看出最终的交集结果是相同的数字只存储一次,因此我们使用unordered_set存储,因为该set查询的时间复杂度为O(1)。算法思路大致是先用unordered_set存储数组nums1,每一个数字只存储一次,然后再查询nums2中的每一个数字,使用nums.find(nums2[i]) != nums.end()进行判断,find函数会查找[begin,end)区间,当find查找失败时,返回end()。然后我们将查找结果插入到result中,当查找成功插入该元素。由于最终返回类型是vector<int>,我们将unordered_set转换为vector返回。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> nums (nums1.begin(), nums1.end());//将nums1转换为unordered_set
        unordered_set<int> result;
        for (int i = 0; i < nums2.size(); i++)
        {
            if (nums.find(nums2[i]) != nums.end()) result.insert(nums2[i]);
        }
        vector<int> result_v(result.begin(), result.end());
        return result_v;
    }
};

快乐数

202. 快乐数

快乐数是指每一位的平方和等于1。

此题的解题关键是如何表示无限循环。当循环过程中有两次的平方和值相等时,会一直在这两个平方和中间循环。因此判断条件就是当前平方和是否已经出现过,那么我们如何判断当前平方和是否出现过呢,就是通过unordered_set实现。判断当前计算出的平方和sum值是否在set中,如果存在,说明无限循环,返回false。如果不存在且值不为1,则将当前平方和sum存入set中。如果值为1,说明每一位的平方和等于1,那么当前数是快乐数。

int newSum(int n)
{
    int sum = 0;
    while (n)
    {
        int n1 = n % 10;
        sum += n1 * n1;
        n /=10;
    }
    return sum;
}
class Solution {
public:
    bool isHappy(int n) {
        int sum = newSum(n);
        unordered_set<int> nums;
        while (nums.find(sum)==nums.end())
        {
            if (sum == 1) return true;
            nums.insert(sum);
            sum = newSum(sum);
        }
        return false;
    }
};

两数之和

1. 两数之和

朴素法:复杂度O(n^2)

给定一个数组和目标值target,判断数组中是否存在两个数的和等于target,如果存在这样的两个数,返回下标。我们可以通过朴素算法即两层for循环实现,第一层指针i进行遍历整个数组,第二层指针j遍历该元素前面的所有元素,当两个元素满足时,返回{i,j}。

可行性:由于第一层遍历整个数组,因此该元素前面的所有元素都会进行配对,因此能够枚举到所有元素对。

哈希表法:复杂度O(n)

该方法能将复杂度从O(n^2)降到O(n)是因为在第二层循环时直接通过unordered_map进行查询,由于unordered_map底层是哈希表,因此查询时间复杂度为O(1)。第一层遍历将nums[i]插入到map中,由于该题存在相同元素,因此用map实现,key是nums[i]的值,value是下标i,pair<int,int>(nums[i],i)因此可以区分相同的key值。在第二层遍历时,直接查询target-nums[i]是否在map中,如果存在,return { i, map.find(target - nums[i])->second } ,first是key,second是value。如果遍历完都没有return,说明不存在,return{}。

完整代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> map;
        for (int i = 0; i < nums.size(); i++)
        {
            if (map.find(target - nums[i]) != map.end()) return { i, map.find(target - nums[i])->second };
            //first是key,second是value,我们将下标保存到value中
            else
            {
                map.insert(pair<int,int>(nums[i],i));
            }
        }
        return {};
    }
};

通过两个数组的交集和两数之和我们可以总结出,当我们相同值元素只存储一次时,使用set,也就是集合,因为集合中的定义就是每种元素只存储一次。当相同元素需要区分时(即都存储),我们使用map,也就是键值对存储,key存储元素值,value存储该元素下标。

  • 28
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值