这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战
字母大小写全排列(题号784)
题目
给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串。返回所有可能得到的字符串集合。
示例:
输入:S = "a1b2"
输出:["a1b2", "a1B2", "A1b2", "A1B2"]
输入:S = "3z4"
输出:["3z4", "3Z4"]
输入:S = "12345"
输出:["12345"]
提示:
S的长度不超过12。S仅由数字和字母组成。
链接
解释
这题啊,这题是经典排列组合
类似的题目其实之前有做过,这里就当作巩固练习吧,熟能生巧。
首先,排列组合就是要找出所有的可能性,那如何找出所有的可能性?
很容易想到的就是从第一个字符开始处理,一点点累加字符串,在累加的过程中处理数字和字母不同的情况,再分别做对应的处理。
照着这个思路来说可能会有几个问题:
-
如何一点点处理?
这里先说说迭代的思路,搞一个数组,它叫
res,初始化值是一个空字符串,也就是''。接下来从字符串的第一个位置开始遍历,遇到新的位置就循环
res内所有的元素,在每个元素后面添加新的字符,有肯能是数字,也有可能是字母如果是数字操作十分简单,给每个元素后面添加就好了
如果是字母则分别添加字母的大小写两种状态
也就是说遇到数字,
res的长度不会变,遇到字母res的长度翻倍,籍此完成遍历即可拿到最后的所有情况 -
如何区分字母和数字?
这里笔者使用的是
Number.isIntegerAPI,可以之间判断出是不是数字,如果不是自然就是字母了,因为题目说了:S仅由数字和字母组成。但还有另外一种方法,利用
charCodeAtAPI来判断,大写字母的区间应该是65到90,小写字母的区间是97到122,如果不在这个区间内的自然是数字了,或者也可以利用数字的区间来进行判断,都是可以的 -
如何确定字母的大小写?
这个笔者每想出来判断的方法,于是很简单的使用了
toUpperCase和toLowerCase这两个API,强行转化成大写和小写,不做任何判断但其实还有另外一种放啊,用异或运算符
^好像可以直接进行转化,这个笔者就不是很清楚了,感兴趣的同学可以去看看
解决完这些问题后代码应该也就出来了。
除去迭代的方法后还有类似的递归操作,整体操作保持不变,将while替换成递归函数即可。
当然,这只是官方推荐的第一种解法,后续的两种解法笔者是真的看不太懂,直接放弃,具体的链接会放在更好的解法这一标题内,感兴趣的同学可以点进去看看。
自己的答案(迭代)
var letterCasePermutation = function(s) {
const res = ['']
for (let i = 0; i < s.length; i++) {
const len = res.length
const item = s.charAt(i)
for (let j = 0; j < len; j++) {
if (Number.isInteger(+item)) {
res[j] = res[j] + item
} else {
res.push(res[j] + item.toUpperCase())
res[j] = res[j] + item.toLowerCase()
}
}
}
return res
};
整体思路和解释中说的别无二异,需要注意的可能就是这行代码了:
const len = res.length
为什么要把这个len提取出来?原因很简单,如果不提取出来,在遇到字母的情况就会出现无限循环了,因为遇到字母需要往res中添加字符串,这样res的长度会不断增加,永远无法走到尽头
所以这里需要提前记录下当前数组的长度,遍历到指定位置就停止,后续都是新增的字符串,不用管它。
自己的答案(递归)
var letterCasePermutation = function(s) {
const res = []
function DFS(i, str) {
if (i === s.length) {
return res.push(str)
}
const item = s.charAt(i)
if (Number.isInteger(+item)) {
DFS(i + 1, str + item)
} else {
DFS(i + 1, str + item.toLowerCase())
DFS(i + 1, str + item.toUpperCase())
}
}
DFS(0, '')
return res
};
递归的判断啊,处理条件啥的都和迭代一样,新增的内容就是递归函数开头的终止条件,这个终止条件也很好理解,就是遍历完了就停止,这里利用字符串的长度来进行判断,其实如果s.charAt()是''也代表递归到头了,用这个条件也是可以的。
其它的就没啥了,基础的递归操作
更好的方法
这块其实有两种解法
- 二分掩码
- 内置函数库
二分掩码利用比特符来进行操作 ,而内置函数库好像是用什么笛卡尔积来算,超纲了超纲了,有兴趣的同学可以点击这里查看官方答案~
PS:想查看往期文章和题目可以点击下面的链接:
这里是按照日期分类的👇
经过有些朋友的提醒,感觉也应该按照题型分类
这里是按照题型分类的👇