[LeetCode] Word Abbreviation 单词缩写

简介:

Given an array of n distinct non-empty strings, you need to generate minimal possible abbreviations for every word following rules below.

  1. Begin with the first character and then the number of characters abbreviated, which followed by the last character.
  2. If there are any conflict, that is more than one words share the same abbreviation, a longer prefix is used instead of only the first character until making the map from word to abbreviation become unique. In other words, a final abbreviation cannot map to more than one original words.
  3. If the abbreviation doesn't make the word shorter, then keep it as original.

Example:

Input: ["like", "god", "internal", "me", "internet", "interval", "intension", "face", "intrusion"]
Output: ["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"]

Note:

  1. Both n and the length of each word will not exceed 400.
  2. The length of each word is greater than 1.
  3. The words consist of lowercase English letters only.
  4. The return answers should be in the same order as the original array.

这道题让我们求单词的缩写形式,就是首尾字母加上中间字符的个数组成的新字符串,但是要求是不能有重复的缩写字符串,而且说明如果缩写字符串的长度并没有减小的话就保留原来的字符串,比如god,缩写成g1d也没啥用,所以仍是god。博主刚开始在研究题目中给的例子的时候有些疑惑,虽然知道internal和interval的缩写形式都是i6l,会冲突,博主刚开始不明白的是,为什么不能一个是i6l,一个是in5l,这样不就不冲突了么,而题目中的缩写形式居然都是原字符串。后来才搞清楚题目原来是说只要有冲突的都不能用,而internal和interval是典型的死杠上的一对,i6l,in5l,int4l,inte3l,inter2l,统统冲突,而再往后的缩写长度就和原字符串一样了,所以二者就都保留了原样。理解了题意就好办了,由于每个单词的缩写形式中数字前面的字母个数不一定相同,所以我们用一个pre数组来记录每个单词缩写形式开头字母的长度,初始化都为1,然后先求出所有单词pre为1的缩写形式,再来进行冲突处理。我们遍历每一个缩写字符串,进行while循环,新建一个集合set,然后遍历其他所有字符串,所有发现冲突字符串,就把冲突字符串的坐标存入集合中,如果没有冲突,那么集合为空,直接break掉,如果由冲突,那么还要把当前遍历的位置i加入结合中,然后遍历集合中所有的位置,对其调用缩写函数,此时pre对应的值自增1,直到没有冲突存在为止,参见代码如下:

public:
    vector<string> wordsAbbreviation(vector<string>& dict) {
        int n = dict.size();
        vector<string> res(n);
        vector<int> pre(n, 1);
        for (int i = 0; i < n; ++i) {
            res[i] = abbreviate(dict[i], pre[i]);
        }
        for (int i = 0; i < n; ++i) {
            while (true) {
                set<int> s;
                for (int j = i + 1; j < n; ++j) {
                    if (res[j] == res[i]) s.insert(j);
                }
                if (s.empty()) break;
                s.insert(i);
                for (auto a : s) {
                    res[a] = abbreviate(dict[a], ++pre[a]);
                }
            }
        }
        return res;
    }
    string abbreviate(string s, int k) {
        return (k >= s.size() - 2) ? s : s.substr(0, k) + to_string(s.size() - k - 1) + s.back();
    }
};

参考资料:

https://discuss.leetcode.com/topic/82613/really-simple-and-straightforward-java-solution

本文转自博客园Grandyang的博客,原文链接:[LeetCode] Word Abbreviation 单词缩写

,如需转载请自行联系原博主。

相关文章
|
3月前
Leetcode(最后一个单词长度)
这篇文章介绍了两种解决LeetCode第58题的方法,即计算给定字符串中最后一个单词的长度,方法包括翻转字符串和逆向遍历统计。
23 0
|
3月前
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
27 0
|
5月前
|
算法
LeetCode第58题最后一个单词的长度
LeetCode第58题"最后一个单词的长度"的解题方法,通过从字符串末尾向前遍历并计数非空格字符,直接得出最后一个单词的长度。
LeetCode第58题最后一个单词的长度
|
5月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
59 4
|
5月前
|
Python
【Leetcode刷题Python】生词本单词整理
文章提供了一个Python程序,用于帮助用户整理和排版生词本上的单词,包括去除重复单词、按字典序排序,并按照特定的格式要求进行打印排版。
48 3
|
5月前
|
Python
【Leetcode刷题Python】318. 最大单词长度乘积
本文提供了LeetCode题目318的Python编程解决方案,题目要求在一个字符串数组中找出两个不含有公共字母的单词,且这两个单词的长度乘积最大,如果不存在这样的两个单词,则返回0。
23 0
|
7月前
|
算法 测试技术 索引
力扣经典150题第三十二题:串联所有单词的子串
力扣经典150题第三十二题:串联所有单词的子串
34 0
|
4月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
65 6
|
5月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
130 2