LeetCode 49_字母异位词分组 c++本地实现(超详细)

续上文找到报错原因之后,更一下49题详细过程,感觉对算法理解又加深了一步。

https://blog.csdn.net/qq_40286920/article/details/124612597?spm=1001.2014.3001.5502


0.浅聊一下unordered_map

  • unordered_map中所有的元素都是pair(对组)
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • unordered_map中不允许有重复元素。
  • unordered_map的底层结构是哈希表。

而C++ STL 标准库中,不仅是 unordered_map 容器,所有无序容器的底层实现都采用的是哈希表存储结构。更准确地说,是用“链地址法”(又称“开链法”)解决数据存储位置发生冲突的哈希表。(也就是同一个key的val会以链表的形式存储,如下图P1,P2,P3的key都是0)

1.题目描述:

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。

示例:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

翻译成人话:

输入:test = {"eat", "tea", "tan", "ate", "nat", "bat"};

输出:

2.题解思路:

利用unordered_map,对每一个源字符串进行排序(同一个分组的异位词排序后相同!!!)。排序后的字符串作为key(索引),将源字符串(未排序的)作为val,以链式结构存放在相应的key后边。

举例,如图从左往右看:

3.本地实现

#include<iostream>
#include<string>
#include<map>
#include<unordered_map>
#include<vector> 
#include<algorithm>//sort()需要

using namespace std;

class Solution
{
public:
	vector<vector<string>> groupAnagrams(vector<string>& strs)
	{
		unordered_map<string, vector<string>> mp;//创建一个无序unordered_map,将排序后的string作为key,原string作为val;
		for (string& str : strs)//创建一个str依次接受strs里的字符串。string& 和 string 的区别:string是拷贝,string&是直接引用修改本身
		{
			string key = str; //拷贝给key
			sort(key.begin(), key.end());//对key进行排序
			mp[key].push_back(str); //把源字符串放在相同的key对应的val。 unordered_map采用开链式结构
		}
		//从哈希表中取出相同key的val,按依次放在vector<vector>容器中
		vector<vector<string>> ans;//建立一个容器ans来存放结果
		for (unordered_map<string, vector<string>>::iterator it = mp.begin(); it != mp.end(); it++)
		{//unordered_map<string, vector<string>>::iterator 等价于 auto
			ans.push_back(it->second);//it->first表示key;it->second表示val;
		}
		return ans;
	}
};

int main()
{
	Solution solution;
	vector<string> test = {"eat", "tea", "tan", "ate", "nat", "bat"};
	vector<vector<string>> res = solution.groupAnagrams(test);
	//遍历大容器
	for (vector<vector<string>>::iterator it = res.begin(); it != res.end(); it++)
	{   //遍历小容器
		for (vector<string>::iterator vit = (*it).begin(); vit != (*it).end(); vit++)//(*it)表示容器 vecotr<string>
		{   //遍历字符串
			for (string::iterator vvit = (*vit).begin(); vvit != (*vit).end(); vvit++)
			{
				cout << (*vvit);
			}
			cout << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

再放一种计数的方法:和我之前做的思路一致。被push论文就不多讲了,不清楚的点这里!

https://blog.csdn.net/qq_40286920/article/details/124541380?spm=1001.2014.3001.5502

原理如图:

class Solution2
{
public:
	vector<vector<string>> groupAnagrams(vector<string>& strs)
	{//容器里不能for(int i = 0; i<;i++)
		map<vector<int>, vector<string>> mp;
		for (string& str : strs)
		{
			vector<int> table(26, 0);
			for (auto it = str.begin(); it != str.end(); it++)
			{
				table[(*it)-'a']++;
			}
			mp[table].push_back(str);
		}
		vector<vector<string>> ans;
		for (auto it = mp.begin(); it != mp.end(); it++)
		{
			ans.push_back(it->second);//it->first表示key;it->second表示val;
		}
		return ans; 
	}
};

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值