[LeetCode] Letter Case Permutation 字母大小写全排列
Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. Return a list of all possible strings we could create.
Examples:
Input: S = "a1b2"
Output: ["a1b2", "a1B2", "A1b2", "A1B2"] Input: S = "3z4"
Output: ["3z4", "3Z4"] Input: S = "12345"
Output: ["12345"]
Note:
Swill be a string with length at most12.Swill consist only of letters or digits.
这道题给了我们一个只包含字母和数字的字符串,让我们将字母以大小写进行全排列,给的例子很好的说明了题意。博主认为这道题给Easy有点不合适,至少应该是Medium的水准。这题主要参考了官方解答贴的解法,我们关心的是字母,数字的处理很简单,直接加上就可以了。比如说S = "abc",那么先让 res = [""],然后res中的每个字符串分别加上第一个字符a和A,得到 ["a", "A"],然后res中的每个字符串分别加上第二个字符b和B,得到 ["ab", "Ab", "aB", "AB"],然后res中的每个字符串分别加上第三个字符c和C,得到 ["abc", "Abc", "aBc", "ABc", "abC", "AbC", "aBC", "ABC"],参见代码如下:
解法一:
class Solution {
public:
vector<string> letterCasePermutation(string S) {
vector<string> res{""};
for (char c : S) {
int len = res.size();
if (c >= '' && c <= '') {
for (string &str : res) str.push_back(c);
} else {
for (int i = ; i < len; ++i) {
res.push_back(res[i]);
res[i].push_back(tolower(c));
res[len + i].push_back(toupper(c));
}
}
}
return res;
}
};
下面这种解法跟上面的解法没有太大的区别,只不过没有用到tolower()和toupper()这两个built-in函数,而是使用了一个trick来flip大小写字母,通过亦或32实现,为什么呢?因为我们知道 'A' = 65, 'B' = 66, 和 'a' = 97, 'b' = 98, 小写字母的ASCII码比大写字母多32,刚好是(1 << 5),那么我们只要flip第五位上的1,就可以实现大小写的交替了,参见代码如下:
解法二:
class Solution {
public:
vector<string> letterCasePermutation(string S) {
vector<string> res{""};
for (char c : S) {
int len = res.size();
if (c >= '' && c <= '') {
for (string &str : res) str.push_back(c);
} else {
for (int i = ; i < len; ++i) {
res.push_back(res[i]);
res[i].push_back(c);
res[len + i].push_back(c ^ );
}
}
}
return res;
}
};
我们再来看一种递归的写法,是一种回溯的思路,比如说S = "abc",用一个pos指向当前处理的位置,初始化带入0,然后再递归函数中,如果pos等于s的长度了,那么将s存入结果res再返回;否则调用递归函数,此时带入pos+1,那么递归函数就会一直深入,直到pos等于s的长度了,那么此时就把"abc"存入结果res了,返回后此时pos=2,发现s[pos]是字母,则用上面解法中的flip方法来翻转字母,并且调用递归函数,这样"abC"就会存入结果res中,然后回溯到pos=1的位置,s[pos]是字符,可以flip,并且调用递归函数,这样"aBC"就会存入结果res中,然后pos继续往后遍历,这样"aBc"就会存入结果res中,然后回溯到pos=0的位置,s[pos]是字符,可以flip,并且调用递归函数,这样"ABc"就会存入结果res中,然后继续回溯,这样"ABC"就会存入结果res中,pos又回溯到1的位置,s[pos]是字符,可以flip,并且调用递归函数,这样"AbC"就会存入结果res中,然后pos继续往后遍历,这样"Abc"就会存入结果res中,整个的顺序为:[abc abC aBC aBc ABc ABC AbC Abc],参见代码如下:
解法三:
class Solution {
public:
vector<string> letterCasePermutation(string S) {
vector<string> res;
helper(S, , res);
return res;
}
void helper(string& s, int pos, vector<string>& res) {
if (pos == s.size()) {
res.push_back(s);
return;
}
helper(s, pos + , res);
if (s[pos] > '') {
s[pos] ^= ;
helper(s, pos + , res);
}
}
};
下面这种解法是官方解答贴的Binary Mask解法,感觉也很巧妙,如果我们仔细观察S = "abc"这个例子,结果会返回8个,为什么是8个呢,因为每个字母都有大小写两种可能,那么三个字母就有2x2x2=8,正好是2的三次方,那么不正好和二进制数相对应么,如果1对应大写字母,0对应小写字母,则有:
-> ABC
-> ABc
-> AbC
-> Abc
-> aBC
-> aBc
-> abC
-> abc
这样的话,我们只需要先统计出S中字母的个数cnt,然后遍历 [0, 2^cnt) 中的每个数字,对于每个数字,再遍历S中的每个字符,如果是字母,那么如果当前位是1,则加入小写字母,反之加入大写字母;如果是数字,则直接加入即可。我们用j指向位,每次处理完一位后j自增1,表示对下一位进行处理,参见代码如下:
解法四:
class Solution {
public:
vector<string> letterCasePermutation(string S) {
vector<string> res;
int cnt = ;
for (char c : S) {
if (c > '') ++cnt;
}
for (int i = ; i < ( << cnt); ++i) {
int j = ;
string word = "";
for (char c : S) {
if (c > '') {
if (((i >> j++) & ) == ) {
word.push_back(tolower(c));
} else {
word.push_back(toupper(c));
}
} else {
word.push_back(c);
}
}
res.push_back(word);
}
return res;
}
};
类似题目:
参考资料:
https://leetcode.com/problems/letter-case-permutation/solution/
https://leetcode.com/problems/letter-case-permutation/discuss/115515/C++-backtrack-solution-w-trick
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Letter Case Permutation 字母大小写全排列的更多相关文章
- Leetcode784.Letter Case Permutation字母大小写全排列
给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串.返回所有可能得到的字符串集合. 示例: 输入: S = "a1b2" 输出: ["a1 ...
- Java实现 LeetCode 784 字母大小写全排列(DFS)
784. 字母大小写全排列 给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串.返回所有可能得到的字符串集合. 示例: 输入: S = "a1b2" ...
- 【Leetcode_easy】784. Letter Case Permutation
problem 784. Letter Case Permutation 参考 1. Leetcode_easy_784. Letter Case Permutation; 2. Grandyang; ...
- [LeetCode] 784. 字母大小写全排列 ☆☆☆(回溯、深度优先遍历)
https://leetcode-cn.com/problems/letter-case-permutation/solution/shen-du-you-xian-bian-li-hui-su-su ...
- 784. Letter Case Permutation
这个题的思想很重要,两种方法 第一种,回溯法 class Solution { public: int sz; vector<string> letterCasePermutation(s ...
- [Swift]LeetCode784. 字母大小写全排列 | Letter Case Permutation
Given a string S, we can transform every letter individually to be lowercase or uppercase to create ...
- 784. Letter Case Permutation C++字母大小写全排列
网址:https://leetcode.com/problems/letter-case-permutation/ basic backtracking class Solution { public ...
- 784. Letter Case Permutation 字符串中字母的大小写组合
[抄题]: Given a string S, we can transform every letter individually to be lowercase or uppercase to c ...
- 【LeetCode】784. Letter Case Permutation 解题报告 (Python&C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 循环 日期 题目地址:https://leet ...
随机推荐
- windows下使用curl命令 && 常用curl命令
什么是curl命令? curl是利用URL语法在命令行方式下工作的开源文件传输工具.它被广泛应用在Unix.多种Linux发行版中,并且有DOS和Win32.Win64下的移植版本. 如何在windo ...
- 第十一节:Bundles压缩合并js和css及原理分析
一. 简介 1.背景:浏览器默认一次性请求的网络数是有上限的,如果你得js和css文件太多,就会导致浏览器需要多次加载,影响页面的加载速度, MVC中提供Bundles的方式压缩合并js和css,是M ...
- 第十五节: EF的CodeFirst模式通过DataAnnotations修改默认协定
一. 简介 1. DataAnnotations说明:EF提供以特性的方式添加到 domain classes上,其中包括两类: A:System.ComponentModel.DataAnnota ...
- [数学笔记Mathematical Notes]1-调和级数发散的一个简单证明
定理. 调和级数 $\dps{\vsm{n}\frac{1}{n}}$ 是发散的. 证明. 设 $$\bex a_n=\sum_{k=1}^n\frac{1}{k}, \eex$$ 则 $a_n$ 递 ...
- [物理学与PDEs]第2章第1节 理想流体力学方程组 1.4 一维理想流体力学方程组
1. 一维理想流体力学方程组 $$\beex \bea \cfrac{\p\rho}{\p t}+\cfrac{\p}{\p x}(\rho u)&=0,\\ \cfrac{\p}{\p t ...
- (一)Java工程化--Maven基础
Maven 读作['mevən] 翻译成中文是"内行,专家" Maven是什么 包依赖的前世今生: 原始的jar包引用--> ant --> maven. 是一种项目管 ...
- java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
♦ 问题所在:项目lib包里少一个jar包 ♦ 解决办法: commons-lang3-3.1.jar 导入到项目就ok
- 用vue 写h5页面-摇一摇
vue配合其他ui框架除了开发一个完整的web项目外,也有不少的项目做一些h5的活动页面开发.你的页面现在需要模拟微信的摇一摇动作. 项目环境: vue-cli 完成的一个项目 准备插件(包):依赖的 ...
- linux 解决Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
第一种: sudo vim /etc/resolv.conf 添加nameserver 8.8.8.8 第二种: /etc/apt/sources.list 的内容换成 deb http://old- ...
- 【web】服务器推送的实现方式(转)
轮询 http流 websocket https://www.cnblogs.com/freud/p/8397934.html http2.0 浅谈Websocket.Ajax轮询和长连接(lon ...