[LeetCode] Group Shifted Strings 群组偏移字符串
Given a string, we can "shift" each of its letter to its successive letter, for example: "abc" -> "bcd". We can keep "shifting" which forms the sequence:
"abc" -> "bcd" -> ... -> "xyz"
Given a list of strings which contains only lowercase alphabets, group all strings that belong to the same shifting sequence.
For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"],
Return:
[
["abc","bcd","xyz"],
["az","ba"],
["acef"],
["a","z"]
]
Note: For the return value, each inner list's elements must follow the lexicographic order.
这道题让我们重组偏移字符串,所谓偏移字符串,就是一个字符串的每个字符按照字母顺序表偏移相同量得到的另一个字符串,两者互为偏移字符串,注意相同字符串是偏移字符串的一种特殊情况,因为偏移量为0。现在给了一堆长度不同的字符串,让把互为偏移字符串的归并到一起,博主最开始想的是建立字符度和该长度的所有偏移字符串的映射,但是很明显的错误是相同长度的不一定都是偏移字符串,比如 'ab' 和 'ba',所以只能用 HashMap 来建立一个字符串和所有和此字符串是偏移字符串的集合之间的映射,由于题目要求结果是按字母顺序的,所以用 multiset 来保存结果,一来可以保存重复字符串,二来可以自动排序。然后博主还写了一个判断二个字符串是否互为偏移字符串的函数,注意在比较两个字母距离时采用了加 26,再对 26 取余的 trick。遍历给定字符串集,对于遍历到的字符串,再遍历哈希表,和每个关键字调用 isShifted 函数来比较,如果互为偏移字符串,则加入其对应的字符串集,并标记 flag,最后遍历完 HashMap,没有跟任何关键字互为偏移,那么就新建一个映射,最后要做的就是把 multiset 转换为 vector 即可,参见代码如下:
解法一:
// Correct but complicated
class Solution {
public:
vector<vector<string>> groupStrings(vector<string>& strings) {
vector<vector<string> > res;
unordered_map<string, multiset<string>> m;
for (auto a : strings) {
bool b = false;
for (auto it = m.begin(); it != m.end(); ++it) {
if (isShifted(it->first, a)) {
it->second.insert(a);
b = true;
}
}
if (!b) m[a] = {a};
}
for (auto it = m.begin(); it != m.end(); ++it) {
res.push_back(vector<string>(it->second.begin(), it->second.end()));
}
return res;
}
bool isShifted(string s1, string s2) {
if (s1.size() != s2.size()) return false;
int diff = (s1[] + - s2[]) % ;
for (int i = ; i < s1.size(); ++i) {
if ((s1[i] + - s2[i]) % != diff) return false;
}
return true;
}
};
上面那个方法挺复杂的,其实有更好的方法,网友的智慧无穷啊,上面那个方法的不高效之处在于对于每个遍历到的字符串,都要和 HashMap 中所有的关键字都比较一次,而其实我们可以更加巧妙的利用偏移字符串的特点,那就是字符串的每个字母和首字符的相对距离都是相等的,比如 abc 和 efg 互为偏移,对于 abc 来说,b和a的距离是1,c和a的距离是2,对于 efg 来说,f和e的距离是1,g和e的距离是2。再来看一个例子,az 和 yx,z和a的距离是 25,x和y的距离也是 25 (直接相减是 -1,这就是要加 26 然后取余的原因),那么这样的话,所有互为偏移的字符串都有个 unique 的距离差,根据这个来建立映射就可以很好的进行单词分组了,这个思路真实太赞了,参见代码如下:
解法二:
class Solution {
public:
vector<vector<string>> groupStrings(vector<string>& strings) {
vector<vector<string> > res;
unordered_map<string, multiset<string>> m;
for (auto a : strings) {
string t = "";
for (char c : a) {
t += to_string((c + - a[]) % ) + ",";
}
m[t].insert(a);
}
for (auto it = m.begin(); it != m.end(); ++it) {
res.push_back(vector<string>(it->second.begin(), it->second.end()));
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/249
类似题目:
参考资料:
https://leetcode.com/problems/group-shifted-strings/
https://leetcode.com/problems/group-shifted-strings/discuss/67442/My-Concise-JAVA-Solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Group Shifted Strings 群组偏移字符串的更多相关文章
- [Swift]LeetCode249.群组偏移字符串 $ Group Shifted Strings
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- LeetCode – Group Shifted Strings
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- [Locked] Group Shifted Strings
Group Shifted Strings Given a string, we can "shift" each of its letter to its successive ...
- LeetCode 249. Group Shifted Strings (群组移位字符串)$
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- [LeetCode] 249. Group Shifted Strings 分组偏移字符串
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- [LeetCode#249] Group Shifted Strings
Problem: Given a string, we can "shift" each of its letter to its successive letter, for e ...
- 249. Group Shifted Strings把迁移后相同的字符串集合起来
[抄题]: Given a string, we can "shift" each of its letter to its successive letter, for exam ...
- Group Shifted Strings -- LeetCode
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- Group Shifted Strings
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
随机推荐
- 安装MYSQL详细教程 版本:mysql-installer-community-5.7.16.0 免安装版本和安装版本出现错误的解决
一.版本的选择 之前安装的Mysql,现在才来总结,好像有点晚,后台换系统了,现在从新装上Mysql,感觉好多坑,我是来踩坑,大家看到坑就别跳了,这样可以省点安装时间,这个折腾了两天,安装了好多个版本 ...
- jQuery对象和DOM对象的区别
jQuery对象和DOM对象使用说明,需要的朋友可以参考下.1.jQuery对象和DOM对象第一次学习jQuery,经常分辨不清哪些是jQuery对象,哪些是 DOM对象,因此需要重点了解jQuery ...
- 我的runloop学习笔记
前言:公司项目终于忙的差不多了,最近比较闲,想起叶大说过的iOS面试三把刀,GCD.runtime.runloop,runtime之前已经总结过了,GCD在另一篇博客里也做了一些小总结,今天准备把ru ...
- JAVA/GUI程序之记事本
自上半年JAVA课程结束后,再也没有看过JAVA了,最近不是很忙,又简单的看了看,本博客纯属记录学习过程,请大神们别笑,其中错误是难免的,毕竟是新手写的博客.下面就进入我们的正题吧,复习GUI时,就想 ...
- 2.ASP.NET MVC 中使用Crystal Report水晶报表
上一篇,介绍了怎么导出Excel文件,这篇文章介绍在ASP.NET MVC中使用水晶报表. 项目源码下载:https://github.com/caofangsheng93/CrystalReport ...
- C#解决界面不响应
在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...
- [Tool] Open Live Writer插件开发
一 前言 Windows Live Writer(简称 WLW)开源之后变成 Open Live Writer(简称 OLW),原先 WLW 的插件在 OLW 下都不能用了,原因很简单,WLW 插件开 ...
- 随便记录下系列 - node->express
随便记录下系列 - node->express 文章用啥写?VsCode. 代码用啥写?VsCode. 编辑器下载:VsCode 一.windows下安装node.js环境: 下载地址 相比以前 ...
- jQuery的案例及必知重要的jQuery选择器
Jquery能做什么 访问和操作DOM元素 控制页面样式 对页面事件进行处理 扩展新的jQuery插件 与Ajax技术完美结合 Jquery的优势 体积小,压缩后只有100KB左右 l强大的选择器 出 ...
- 块级标签包含行内标签底部出现3px间隔的解决办法
当块级标签(如div)内包含了行内标签(如img),则外层元素与内层元素底部会出现3px的间隔: 代码如下: <!doctype html> <html lang="en& ...