暑期算法训练.12

目录

[52. 力扣1 两数之和](#52. 力扣1 两数之和)

[52.1 题目解析:](#52.1 题目解析:)

[52.2 算法思路:](#52.2 算法思路:)

[52.3 代码演示:](#52.3 代码演示:)

​编辑

[52.4 总结反思:](#52.4 总结反思:)

[53 面试题:判定是否互为字符重排](#53 面试题:判定是否互为字符重排)

[53.1 题目解析:](#53.1 题目解析:)

[53.2 算法思路:](#53.2 算法思路:)

[53.3 代码演示:](#53.3 代码演示:)

​编辑

[53.4 总结反思](#53.4 总结反思)

[54. 力扣217 存在重复元素I](#54. 力扣217 存在重复元素I)

[54.1 题目解析:](#54.1 题目解析:)

[54.2 算法思路:](#54.2 算法思路:)

[54.3 代码演示:](#54.3 代码演示:)

​编辑

54.4总结反思:

[55. 力扣219 存在重复的元素II](#55. 力扣219 存在重复的元素II)

[55.1 题目解析:](#55.1 题目解析:)

​编辑

[55.2 算法思路:](#55.2 算法思路:)

[55.3 代码演示:](#55.3 代码演示:)

​编辑

[55.4 总结反思](#55.4 总结反思)

[56. 力扣49 字母异位词分组](#56. 力扣49 字母异位词分组)

[56.1 题目解析:](#56.1 题目解析:)

​编辑

[56.2 算法思路:](#56.2 算法思路:)

[56.3 代码演示:](#56.3 代码演示:)

​编辑

[56.4 总结反思:](#56.4 总结反思:)


今天的算法题是我从暑假写博客以来最简单的一次。废话少说,开启今天的算法题

在此之前,咱们要先讲一下哈希表:

1.哈希表是什么?(哈希表使用方式比较单一),它是存储数据的容器。

2.那么哈希表有啥用呢?快速查找某个元素,基本接近O(1)级别。

3.什么时候用哈希表?当频繁的查找某一个数的时候用哈希表,或者使用二分查找,但是二分查找局限性比较大。你用哈希表是因为哈希表比较快,但是呢,能用二分查找还是用二分查找,因为哈希表是典型的用空间换时间。

4.怎么用哈希表?1.容器(哈希表)2.使用数组模拟简易的哈希表。一般适用于:

【1】字符串中的"字符",(基本创建一个大小为200的数组空间即可),<index,n[index]>

【2】数据范围比较小的时候,比如int,1~10^3或4或5,每一个下标对应一个数,但是当出现负数的话,就不建议使用了。

OK,那么关于哈希表的前置知识已经讲完了,那么接下来,就正式的进入咱们今天的讲题阶段

52. 力扣1 两数之和

52.1 题目解析:

本题很简单的题目吧。

52.2 算法思路:

那么这个题目,咱们可以使用暴力枚举来做,不过这个暴力枚举,并不是非常干脆的暴力枚举,还是需要一点智慧的。那么下面我就举个例子,大家看一看。

就是固定住一个数字,然后,从这个固定的数字后面去寻找对应的数字即可。那么此时就有两种寻找方式,一个是从前往后,一个是从后往前

优化:

那么咱们对于这种暴力解法,咱们该如何优化呢?

优化就是根据前面的暴力解法来进行的优化,由上面的解析可以看出优化的结果。

52.3 代码演示:

cpp 复制代码
vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> hash;//<nums[i],i>
    for (int i = 0; i < nums.size(); i++)
    {
        int x = target - nums[i];//这个是在哈希表中找到这个数
        if (hash.count(x)) return { hash[x],i };//这个hash[x],返回的是x的下标。count,如果哈希表中有这个key,就返回1,否则,返回0
        hash[nums[i]] = i;//如果没有这个数字,那么就存储这个数字,并且存下这个数字的下标,因为上面那行代码需要用到下标
    }
    return { -1,-1 };
}
int main()
{
    vector<int> nums = { 2,7,11,15 };
    int target = 9;
    vector<int> outcome = twoSum(nums, target);
    for (auto& e : outcome)
    {
        cout << e << "";
    }
    cout << endl;
    return 0;
}

52.4 总结反思:

本题基本就用到咱们之前所讲的那些东西,这里创建哈希表使用unordered_map,是因为这里有key以及val,不只是key

53 面试题:判定是否互为字符重排

53.1 题目解析:

题目也会相当的简单,而且,咱们上面也说了,只要是关于字符串存储的,都可以使用到哈希表

53.2 算法思路:

那么本题就是使用哈希表,使用一个,这里有一个细节,就是遍历s1的字符之后,再遍历s2。如果在s2找到与s1相同的字符,就减一,如果最后减到负数,则返回false。并且若两个字符串长度不相等则直接返回false即可。

53.3 代码演示:

cpp 复制代码
bool CheckPermutation(string s1, string s2) {
    if (s1.size() != s2.size()) return false;
    int hash[26] = { 0 };
    for (auto& e : s1)
    {
        hash[e - 'a']++;
    }
    for (auto& e : s2)
    {
        hash[e - 'a']--;
        if (hash[e - 'a'] < 0) return false;
    }
    return true;
}
int main()
{
    string s1("abc");
    string s2("bca");
    cout << CheckPermutation(s1, s2) << endl;
    return 0;
}

53.4 总结反思

基本也是用到了咱们开篇所讲的那些知识

54. 力扣217 存在重复元素I

54.1 题目解析:

这题目更不需要多说

54.2 算法思路:

那么咱们这一题主要就是使用哈希表去完成:

这一道题与那个两数之和的题目策略很像,咱们可以使用那个策略去做,也是使用哈希表,只不过,这一次,只需要有一个key值即可,不需要存val,所以使用unordered_set即可。

54.3 代码演示:

cpp 复制代码
bool containsDuplicate(vector<int>& nums)
{
    unordered_set<int> hash;
    for (auto e : nums)
    {
        if (hash.count(e)) return true;
        hash.insert(e);
    }
    return false;
}
int main()
{
    vector<int> nums = { 1,2,3,1 };
    cout << containsDuplicate(nums) << endl;
    return false;
}

54.4总结反思:

基本的重要的知识,学会运用,做题轻轻松松

55. 力扣219 存在重复的元素II

55.1 题目解析:

这个题目与前面的那一个题目很像,只是多了一个条件而已

55.2 算法思路:

由于这个得使用到下标,所以咱们还是使用unordered_map进行创建哈希表

55.3 代码演示:

cpp 复制代码
bool containsNearbyDuplicate(vector<int>& nums, int k) {
    unordered_map<int, int> hash;
    for (int i = 0; i < nums.size(); i++)
    {
        if (hash.count(nums[i]))
        {
            if ((i - hash[nums[i]]) <= k) return true;

        }
        hash[nums[i]] = i;
    }
    return false;
}
int main()
{
    vector<int> nums = { 1,2,3,1 };
    int k=3;
    cout << containsNearbyDuplicate(nums, k) << endl;
    return 0;
}

55.4 总结反思

那么大体的思路基本就是这样,大家还是得利用好前面的知识才可以

56. 力扣49 字母异位词分组

56.1 题目解析:

这个题目很简单,就是具有相同的字母的字符串就可以合成一组异位词。

56.2 算法思路:

这个还是得使用哈希表,1.判断两个字符是否为字母异位词,排序

2.然后就是如何分组?<string,string[]>,第二个存的是字符数组。例如,"aet","tea"若字符串中有这个字母,那么加入到字符串数组即可

即val就是咱们所要的结果

56.3 代码演示:

cpp 复制代码
vector<vector<string>> groupAnagrams(vector<string>& strs)
{
    unordered_map<string, vector<string>> hash;
    // 1. 把所有的字⺟异位词分组

        for (auto& s : strs)
        {
            string tmp = s;
            sort(tmp.begin(), tmp.end());
            hash[tmp].push_back(s);
        }
    // 2. 结果提取出来

        vector<vector<string>> ret;
    for (auto& [x, y] : hash)
    {
        ret.push_back(y);
    }
    return ret;
}
int main()
{
    vector<string> str = { "eat", "tea", "tan", "ate", "nat", "bat" };
    vector<vector<string>> outcome = groupAnagrams(str);
    for (auto& e : outcome)
    {
        for (auto& x : e)
        {
            cout << x << "";
        }
        cout << endl;
    }
    
    return 0;
}

56.4 总结反思:

基本今天的题目就是这些,算是比较简单的。

本篇完....................