代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和...

一、有效的字母异位词

链接:力扣1

描述:

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和..._第1张图片

思路:数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。

字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。

再遍历 字符串s的时候,只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。

统计完s中的字符以后,如何判断t中的字符呢?只需要同样遍历一遍,对hashtable中相应的索引减一,最后看hashtable中是否全为0,只要有一个非零,那么就返回false,全为0,则返回true


代码如下:

#include 
using namespace std;
class Solution
{
public:
	bool isAnagram(string s, string t)
	{
		int hashtable[26] = { 0 };
		for (int i = 0; i < s.size(); i++)
		{
			hashtable[s[i] - 'a']++;
		}
		for (int j = 0; j < t.size(); j++)
		{
			hashtable[t[j] - 'a']--;
		}
		//思考了很久,如果一旦有一个不为0,则说明有字母不一样
		for (int i = 0; i < 26; i++)
		{
			if (hashtable[i])
				return false;
		}
		return true;
	}
};

int main()
{
	string s = "anagram";
	string t = "nagaram";
	Solution q;
	cout<

运行结果:

代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和..._第2张图片


二、两个数组的交集

链接:力扣2

描述:给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序


思路:

1、暴力求解。两个for循环,因为最后的结果中的交集是无重复的,所以用一个set容器来存放结果。最后可直接用set的迭代器返回一个vector容器。

2、用unordered_set容器做hashtable,因为最后的结果中的交集是无重复的,所以用一个unordered_set容器来存放结果。同时将其中一个容器nums1转为哈希表,遍历另外一个容器,利用set的查找功能,如果在hashtable中,就存在结果容器里。

for (int num : nums2)的写法值得注意,数组也可以这么干。


#include
#include 
#include 
using namespace std;

class Solution
{
public:
	vector intersection(vector& nums1, vector& nums2)
	{
		unordered_set result_set;
		unordered_set nums_set(nums1.begin(), nums1.end());//转换
		for (int num : nums2)
		{
			//发现nums2的元素,在nums_set的出现过
			if (nums_set.find(num) != nums_set.end())
			{
				result_set.insert(num);
			}
		}
		return vector(result_set.begin(), result_set.end());
	}
};
int main()
{
	Solution s;
	vectorv1{ 2,4,7,5,5 };
	vectorv2{ 2,5,5 };
	vectorret= s.intersection(v1, v2);
	return 0;
}

结果如下:

代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和..._第3张图片

 


三、快乐数

链接:力扣3

描述:

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

    对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
    然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
    如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和..._第4张图片

 思路:

既然需要求每个位置上的和,那么可以先写一个成员函数求各个位置的和。题目告诉了可能出现无限循环,那么如果某次的和等于之前求出来的和了,说明陷入了无限循环,即不是快乐数。因此需要记录之前的和,所以要用unordered_set记录出现的sum。先判断第一次的sum是否为1,是1就返回true,如果某次查找到了sum在set里,则返回false,接着加入set里。


代码如下:

#include 
#include 
using namespace std;
class Solution {
public:
    int Getsum(int n)
    {
        int sum = 0;
        //求每个位置上的数字平方和
        while (n)
        {
            sum += pow((n % 10), 2);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n)
    {
        unordered_sets;
        while (1)
        {
            int sum = this->Getsum(n);
            if (sum == 1)
                return true;
            if (s.find(sum) != s.end())
            {
                //如果在unordered_set中找到了重复值,说明陷入循环了
                //就不是快乐数了
                return false;
            }
            s.insert(sum);
            n = sum;
        }
    }
};
int main()
{
    Solution s;
    cout<

运行结果:

代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和..._第5张图片


 

四、两数之和。

链接:力扣4

描述:

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和..._第6张图片


思路:

四点内容:

1、什么时候使用哈希法?当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。

本题呢,我就需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去查询这个集合,需要查找的元素是target-nums[i],是否出现在这个集合。如果存在,则返回查找到的下标和当前遍历的下标。

2、用哪种哈希结构?

  • 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
  • set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。

这道题目中并不需要key有序,选择std::unordered_map 效率更高!只能用unordered_map,不仅可以存元素,还可以存元素下标。需要用key存元素,value存下标。

3、map里存的什么数?

存的之前遍历过的数组元素以及下标。每次都需要在map里查找,查找成功就返回,否则就加入。


代码如下:

#include 
#include 
#include 
using namespace std;
class Solution {
public:
    vector twoSum(vector& nums, int target) 
    {
        unordered_mapm;
        for (int i = 0; i < nums.size(); i++)
        {
            int s = target - nums[i];
            unordered_map::iterator mit = m.find(s);
            if (mit != m.end())
            {
                //找到了该值
                return vector{(*mit).second,i};
            }
            else
                m.insert(make_pair(nums[i], i));
        }
        return vector{};
    }
};

int main()
{
    Solution s;
    vectorv{ 2, 7, 11, 15 };
    vectorret = s.twoSum(v, 9);
    return 0;
}

结果如下:

代码随想录算法学习5 |242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和..._第7张图片

 

你可能感兴趣的:(算法,c++,leetcode,数据结构)