《算法题讲解指南:优选算法-哈希表》--56.两数之和,57.判断是否互为字符重排

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

哈希表简介:

56.两数之和

题目链接:

题目描述:

题目示例:

解法(哈希表):

算法思路:

C++算法代码(暴力枚举):

C++算法代码(哈希表):

算法总结及流程解析:

57.判断是否互为字符重排

题目链接:

题目描述:

题目示例:

解法(哈希表):

算法思路:

C++算法代码(两个哈希表):

C++算法代码(优化:一个哈希表):

算法总结及流程解析:

结束语


哈希表简介:

56.两数之和

题目链接:

1. 两数之和 - 力扣(LeetCode)

题目描述:

题目示例:

解法(哈希表):

算法思路:

如果我们可以事先将「数组内的元素」和「下标」绑定在一起存入「哈希表」中,然后直接在哈希表中查找每一个元素的target-nums[i],就能快速的找到「目标和的下标」。

这里有一个小技巧,我们可以不用将元素全部放入到哈希表之后,再来二次遍历(因为要处理元素、相同的情况)。而是在将元素放入到哈希表中的「同时」,直接来检查表中是否已经存在当前元素所对应的目标元素(即target-nums[i])。如果它存在,那我们已经找到了对应解,并立即将其返回。无需将元素全部放入哈希表中,提高效率。

因为哈希表中查找元素的时间复杂度是0(1),遍历一遍数组的时间复杂度为0(N),因此可以

将时间复杂度降到 O(N)。

这是一个典型的「用空间交换时间」的方式。

C++算法代码(暴力枚举):

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        //解法一:暴力枚举(时间复杂度:O(N^2) )
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            for(int j = i + 1; j < n; j++)
            {
                if(nums[i] + nums[j] == target)
                {
                    return {i, j};
                }
            }
        }
        return {};
    }
};

C++算法代码(哈希表):

cpp 复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        //解法二:哈希表
        int n = nums.size();
        unordered_map<int, int> hash; //<nums[i], i>
        //将数组每个值放入哈希表中,并且对应的值(value)是下标
        for(int i = 0; i < n; i++)
        {
            if(hash.count(target - nums[i]))
            {
                return {hash[target - nums[i]], i};
                //hash[target - nums[i]]对应的就是前面一个值的下标
            }
            else
            {
                //为0则说明前面没有值和nums[i]相加为target
                //则插入哈希表
                hash[nums[i]] = i;
            }
        }
        return {};
    }
};

算法总结及流程解析:

57.判断是否互为字符重排

题目链接:

面试题 01.02. 判定是否互为字符重排 - 力扣(LeetCode)

题目描述:

题目示例:

解法(哈希表):

算法思路:

1.当两个字符串的长度不相等的时候,是不可能构成互相重排的,直接返回 false;

2.如果两个字符串能够构成互相重排,那么每个字符串中「各个字符」出现的「次数」一定是相同的。因此,我们可以分别统计出这两个字符串中各个字符出现的次数,然后逐个比较是否相等即可。这样的话,我们就可以选择「哈希表」来统计字符串中字符出现的次数。

C++算法代码(两个哈希表):

cpp 复制代码
class Solution {
public:
    bool CheckPermutation(string s1, string s2) 
    {
        //解法:两个哈希表
        int hash1[26] = {0};
        int hash2[26] = {0};    
        for(int i = 0; i < s1.size(); i++)
        {
            hash1[s1[i] - 'a']++;
        }
        for(int i = 0; i < s2.size(); i++)
        {
            hash2[s2[i] - 'a']++;
        }
        for(int i = 0; i < 26; i++)
        {
            if(hash1[i] != hash2[i])
            {
                return false;
            }
        }
        return true;
    }
};

C++算法代码(优化:一个哈希表):

cpp 复制代码
class Solution {
public:
    bool CheckPermutation(string s1, string s2) 
    {
        //优化:一个哈希表
        if(s1.size() != s2.size())
        {
            return false;
        }
        int hash[26] = {0};
        for(int i = 0; i < s1.size(); i++)
        {
            hash[s1[i] - 'a']++;
        }
        for(int i = 0; i < s2.size(); i++)
        {
            hash[s2[i] - 'a']--;
        }
        for(int i = 0; i < 26; i++)
        {
            if(hash[i] != 0)
            {
                return false;
            }
        }
        return true;
    }
};

算法总结及流程解析:

结束语

到此,56.两数之和,57.判断是否互为字符重排 这两道算法题就讲解完了。两数之和,对比了暴力枚举(O(n²))和哈希表(O(n))两种解法,后者通过空间换时间优化效率;判断是否互为字符重排,通过统计字符出现次数进行比较,提供了使用两个哈希表和优化为一个哈希表的两种实现方式。希望大家能有所收获!

相关推荐
米粒12 小时前
力扣算法刷题 Day23
数据库·算法·leetcode
BFT白芙堂2 小时前
基于 Kinova Gen3 机械臂的家庭人机交互安全算法研究
人工智能·深度学习·算法·安全·人机交互·模型训练·具身智能
计算机安禾2 小时前
【数据结构与算法】第8篇:线性表(四):双向链表与循环链表
c语言·开发语言·数据结构·c++·算法·链表·visual studio
tankeven2 小时前
HJ149 数水坑
c++·算法
John_ToDebug10 小时前
浏览器扩展延迟加载优化实战:如何让浏览器启动速度提升50%
c++·chrome·windows
是娇娇公主~10 小时前
C++ 中 std::deque 的原理?它内部是如何实现的?
开发语言·c++·stl
Fly Wine11 小时前
Leetcode之有效字母异位词
算法·leetcode·职场和发展
程序员夏末12 小时前
【LeetCode | 第七篇】算法笔记
笔记·算法·leetcode
luanma15098013 小时前
PHP vs C++:编程语言终极对决
开发语言·c++·php