【今日力扣】javascript 字符串排列

给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。换句话说,第一个字符串的排列之一是第二个字符串的子串。
  • 初始思路:列出s1全排列(递归),判断是否是s2子串,超时
    只展示全排列部分,判断是否是子串用includes方法+循环
/*递归思路:
*例如输入字符串'bcd',先取出b,然后是c,直到最后一位d,将c插入0d0的
*为0的位置,得到cd、dc;将b插入0c0d0、0d0c0为0的位置,得到bcd、cbd、
*cdb和bdc、dbc、dcb;以此类推。显然,字符串一旦长度过长,就完蛋
*/
function recursion(s1){
        if(s1.length==1){ // 当输入字符串或者剩余字符串只有一个字母时,返回该字母
            return [s1];
        }else{
            let left=s1[0]; // 取出s1左端字符,作为待插入字符
            let rest=s1.slice(1,s1.length); // 取出剩余字符串
            let arr=[];
            var result=recursion(rest); //递归
            for(let i=0;i<result.length;i++){
                for(let j=0;j<=result[i].length;j++){
                    // 插入字符left到各个为0(空)位置
                    let per=result[i].slice(0,j)+left+result[i].slice(j);
                    arr.push(per);
                }
            }
            return arr;
        }

同时还学到一个简易的数组去重的方法(es6的set对象类似数组,但成员唯一,不会有重复的值):

let ar=Array.from(new Set(arr)); // arr为待去重字符串

踩坑的点:

  1. 牵扯到字符串的输入时,记得判空,length==0即可。也就是说空数组也有length属性
  2. 使用length属性时一定要注意是否运行到某阶段时其对象已经失去了length属性导致报错:“length” undefined



  • 改进思路:滑动窗口,以s1长度固定窗口,以窗口形式在s2上从0到末尾滑动,相比于之前代码及其简洁
    其实,比较是否某种排列是s2子串不需要得出s1全排列,只要比较s2子串是否含有s1里的所有字符,与顺序无关,所以用sort排序比较是否相等
var checkInclusion = function(s1, s2) {
    let len = s1.length; // 固定窗口长度
    let sort1 = s1.split("").sort().toString(); // 排序
    for (let right = 0; right <= s2.length - len; right++) {
        let subStr = s2.substr(right, len); // s1窗口滑过的s2部分
        if (sort1 === subStr.split("").sort().toString()) {
        // 比较窗口与s2该部分是否对应
            return true;
        }
    }
    return false;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值