[LeetCode] Generalized Abbreviation 通用简写

简介:

Write a function to generate the generalized abbreviations of a word.

Example:

Given word = "word", return the following list (order does not matter):

["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]

这道题让我们对一个单词进行部分简写,简写的规则是若干个字母可以用数字来表示,但是不能有两个相邻的数字,具体可以参考题目中给的例子,根据我以往的经验,这种列举所有情况的必定是要用DFS来写的,但是我一时半会又没想到该咋递归,后来我数了一下题目中给的例子的所有情况的个数,是16个,而word有4个字母,刚好是2的4次方,这是巧合吗,当然不是,后来我又发现如果把0到15的二进制写出来,每一个可以对应一种情况,如下所示:

0000 word
0001 wor1
0010 wo1d
0011 wo2
0100 w1rd
0101 w1r1
0110 w2d
0111 w3
1000 1ord
1001 1or1
1010 1o1d
1011 1o2
1100 2rd
1101 2r1
1110 3d
1111 4

那么我们就可以观察出规律,凡是0的地方都是原来的字母,单独的1还是1,如果是若干个1连在一起的话,就要求出1的个数,用这个数字来替换对应的字母,既然规律找出来了,那么代码就很好写了,如下所示:

解法一:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res;
        for (int i = 0; i < pow(2, word.size()); ++i) {
            string out = "";
            int cnt = 0, t = i;
            for (int j = 0; j < word.size(); ++j) {
                if (t & 1 == 1) {
                    ++cnt;
                    if (j == word.size() - 1) out += to_string(cnt);
                } else {
                    if (cnt != 0) {
                        out += to_string(cnt);
                        cnt = 0;
                    }
                    out += word[j];
                }
                t >>= 1;
            }
            res.push_back(out);
        }
        return res;
    }
};

上述方法返回结果的顺序为:

["word","1ord","w1rd","2rd","wo1d","1o1d","w2d","3d","wor1","1or1","w1r1","2r1","wo2","1o2","w3","4"]

我们可以对上面代码稍稍改写一下,变的稍微简洁一点: 

解法二:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res;
        for (int i = 0; i < pow(2, word.size()); ++i) {
            string out = "";
            int cnt = 0;
            for (int j = 0; j < word.size(); ++j) {
                if ((i >> j) & 1) ++cnt;
                else {
                    if (cnt != 0) {
                        out += to_string(cnt);
                        cnt = 0;
                    }
                    out += word[j];
                }
            }
            if (cnt > 0) out += to_string(cnt);
            res.push_back(out);
        }
        return res;
    }
};

那么迭代的写法看完了,来考虑一些递归的写法吧,上网搜了一下,发现下面三种写法比较容易理解, 

解法三:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res{word};
        helper(word, 0, res);
        return res;
    }
    void helper(string word, int pos, vector<string> &res) {
        for (int i = pos; i < word.size(); ++i) {
            for (int j = 1; i + j <= word.size(); ++j) {
                string t = word.substr(0, i);
                t += to_string(j) + word.substr(i + j);
                res.push_back(t);
                helper(t, i + 1 + to_string(j).size(), res);
            }
        }
    }
};

上述方法返回结果的顺序为:

["word","1ord","1o1d","1o2","1or1","2rd","2r1","3d","4","w1rd","w1r1","w2d","w3","wo1d","wo2","wor1"]

解法四:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res;
        helper(word, 0, 0, "", res);
        return res;
    }
    void helper(string word, int pos, int cnt, string out, vector<string> &res) {
        if (pos == word.size()) {
            if (cnt > 0) out += to_string(cnt);
            res.push_back(out);
        } else {
            helper(word, pos + 1, cnt + 1, out, res);
            helper(word, pos + 1, 0, out + (cnt > 0 ? to_string(cnt) : "") + word[pos], res);
        }
    }
};

上述方法返回结果的顺序为:

 ["4","3d","2r1","2rd","1o2","1o1d","1or1","1ord","w3","w2d","w1r1","w1rd","wo2","wo1d","wor1","word"]

解法五:

class Solution {
public:
    vector<string> generateAbbreviations(string word) {
        vector<string> res;
        res.push_back(word.size() == 0 ? "" : to_string(word.size()));
        for (int i = 0; i < word.size(); ++i) {
            for (auto a : generateAbbreviations(word.substr(i + 1))) {
                string left = i > 0 ? to_string(i) : "";
                res.push_back(left + word.substr(i, 1) + a);
            }
        }
        return res;
    }
};

本文转自博客园Grandyang的博客,原文链接:通用简写[LeetCode] Generalized Abbreviation ,如需转载请自行联系原博主。

相关文章
|
9月前
|
供应链 监控 安全
业务上云的主要安全风险及网络安全防护建议
业务上云面临数据泄露、配置错误、IAM风险、DDoS攻击、合规与审计、供应链及内部威胁等安全挑战。建议采取全生命周期加密、自动化配置检查、动态权限管理、流量清洗、合规性评估、供应链可信验证及操作审批等措施,构建“预防-检测-响应”一体化安全体系,确保数据保护、权限收敛、合规审计和弹性防护,保障云端业务安全稳定运行。
1210 1
|
SpringCloudAlibaba 前端开发 Java
SpringCloud Alibaba微服务实战三十六 - 使用Feign的一些问题以及如何解决?
SpringCloud Alibaba微服务实战三十六 - 使用Feign的一些问题以及如何解决?
1317 0
|
关系型数据库 MySQL 程序员
在 Windows 命令提示符下启动 MySQL:net start mysql 发生系统错误 5。 拒绝访问。解决方式小结
在 Windows 命令提示符下启动 MySQL:net start mysql 发生系统错误 5。 拒绝访问。解决方式小结
1416 1
在 Windows 命令提示符下启动 MySQL:net start mysql 发生系统错误 5。 拒绝访问。解决方式小结
|
Java Android开发 开发者
《阿里巴巴Android开发手册》电子版地址
本手册以开发者为中心视角分为Java语言规范,Android资源文件命名与使用,Android基本组件,UI与布局等九大部分。
1282 0
《阿里巴巴Android开发手册》电子版地址
|
C语言
【Qt】打开现有 Qt 项目 ( 打开已存在的项目 | 运行打开的项目 )
【Qt】打开现有 Qt 项目 ( 打开已存在的项目 | 运行打开的项目 )
785 0
【Qt】打开现有 Qt 项目 ( 打开已存在的项目 | 运行打开的项目 )
|
21小时前
|
云安全 人工智能 自然语言处理
|
5天前
|
搜索推荐 编译器 Linux
一个可用于企业开发及通用跨平台的Makefile文件
一款适用于企业级开发的通用跨平台Makefile,支持C/C++混合编译、多目标输出(可执行文件、静态/动态库)、Release/Debug版本管理。配置简洁,仅需修改带`MF_CONFIGURE_`前缀的变量,支持脚本化配置与子Makefile管理,具备完善日志、错误提示和跨平台兼容性,附详细文档与示例,便于学习与集成。
314 116
|
8天前
|
数据采集 人工智能 自然语言处理
Meta SAM3开源:让图像分割,听懂你的话
Meta发布并开源SAM 3,首个支持文本或视觉提示的统一图像视频分割模型,可精准分割“红色条纹伞”等开放词汇概念,覆盖400万独特概念,性能达人类水平75%–80%,推动视觉分割新突破。
554 51
Meta SAM3开源:让图像分割,听懂你的话