当前位置: 首页 > Web前端 > HTML

前端系列-查找字符串B中的任意字符组合是否是字符串A的子串

时间:2023-04-02 23:01:04 HTML

题目要求前端面试可能会遇到这道算法题,据说这道题有人问过在其中之一。查找字符串B中的任意字符组合是否为字符串A的子串。例如A=abc123,B=cba,则B的其中一个组合abc是A的子串,则返回true。算法思想题目的来源无从考证。接下来,我们将从JavaScript的角度来封装这样一个功能函数。第一眼看到这个问题,你会想到什么?我想到的是先把B的所有排列组合都列出来,存入数组,然后遍历判断是否有A中包含的组合,有则返回true,否则返回false。如果我们从题中给出的例子去穷举,一共有6种组合,很容易穷举出来,但是当字符串的长度很大的时候怎么办呢?所以穷举法被我排除了。标记删除方法的名字听起来很奇怪,是什么意思?1、A的排序必须保持不变。由于我们很难从变量入手,所以我们可以从不变的地方入手,以相同的方式响应所有的变化。2.我可能不习惯看字符串。我将A和B都转换为数组。leta=A.split('')//[a,b,c,1,2,3]letb=B.split('')//[c,b,a]3.首先过滤数组as为空的情况下,如果a或b为空,则不需要比较,返回false。if(a.length===0||b.length===0){returnfalse}4.只看数组b,可以有6种排列组合,[c,b,a],[a,b,c],[a,c,b],[b,a,c],[b,c,a],[c,a,b]。记住第一步说的,不管b有多少种组合,我们从a开始。//a=[a,b,c,1,2,3]for(letj=0;j0){//当前遍历的数组b中存在数组aelementofif(b.indexOf(a[j])>-1){//删除b数组中匹配到的下标对应的第一个元素b.splice(b.indexOf(a[j]),1)if(b.length===0){//如果数组b全部删除,则证明b是a的子串返回true}}else{//数组b没有当前遍历数组的元素b,restorebarrayb=B.split('')}}else{//数组b为空返回truereturntrue}}综上,在和其他前端的交流中也学到了其他的解题思路工程师,其中一些非常有趣。比如考虑用Map或者Set,slider区间比较等,但是我没有用代码实现。如果你有其他方法,可以在下方留言。完整源码评论区有人指出无法覆盖某些场景的测试用例,所以我对上面的具体过程进行了改进。以下是改进后的源代码。添加了两个字段,isBack和isRestart。isRestart用于标记是否在当前位置再次遍历,isBack决定是否返回数组遍历一个单位的下标。varA='abc123',B='cba'functioninterface(A,B){//将A和B转换为数组leta=A.split('')letb=B.split('')if(a.length===0||b.length===0){returnfalse}letisBack=false,isRestart=0//遍历数组afor(letj=0;j0){isBack=false//数组a有当前遍历的数组b的元素if(b.indexOf(a[j])>-1){//删除b数组中匹配到的下标对应的第一个元素b.splice(b.indexOf(a[j]),1)if(b.length===0){//如果数组b是all被删除,证明b是a的子串returntrue}}else{if(isRestart!==0){isBack=false}else{isBack=true}//数组b不存在数组b的元素当前遍历,恢复b数组b=B.split('')if(isBack){j-=1isRestart=0}isRestart++}}else{//数组b为空returntruereturntrue}}returnfalse}interface(A,B)