[js代码练习]递归实现全排列及流程梳理

问题描述:

给出一个字符串,找到它的所有排列。

示例如:

输入'abc',
输出[ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ]

输入'abb',
输出[ 'abb', 'bab', 'bba' ]

输入'abbc',
输出[
  'abbc', 'abcb',
  'acbb', 'babc',
  'bacb', 'bbac',
  'bbca', 'bcab',
  'bcba', 'cabb',
  'cbab', 'cbba'
]

参考https://blog.csdn.net/weixin_33912445/article/details/91421539

重点就是始终记住js是 “解释执行”的这个特点,执行是从上到下的。在没有异步的情况下,js代码是不能跳过前面的代码 去执行后面的代码的。也就是说递归的函数必须执行到最后,才能开始之后的代码

const Cstr = 'abc'

let Arr = Cstr.split('') //字符串转化为数组


function permutate(Arr){
  let result = []

  if(Arr.length > 1){ //若数组长度大于1,执行下一步
    for(let i = 0; i < Arr.length; i++){ 
      let temp = Arr[i] //取出当前字母
      let newArr = permutate(Arr.slice(0,i).concat(Arr.slice(i+1,Arr.length))) //拼接除当前字母以外的字母成数组,并开始递归
      for(let i = 0; i < newArr.length; i++){
        result.push(temp + newArr[i].toString()) //当前字母加排列的字母组合
      }
    }
  }else if(Arr.length === 1){
    result.push(Arr)
  }
  return result
}

let finalArr = []
permutate(Arr).forEach(item => { //去重
  if(!finalArr.some(item2 => item2 === item)){
    finalArr.push(item)
  }
})

console.log(finalArr);

流程梳理:(以字符串'abc'为例)

  1. 开始,temp等于a,数组拼接后得到[b,c],开启第一次递归
  2. [b,c]进入后,新的temp(2)等于b,数组拼接后得到[c],开启第二次递归
  3. [c]进入后,直接push到result里,第二次递归直接结束
  4. 返回到第一次递归,从第二次递归传递来的result为[[c]],即第一次递归的newArr为[[c]]
  5. 接着继续执行第一次递归的代码(从console.log(newArr);开始)
  6. 第一次temp(2)+newArr[i].toString为b+c,即bc,result此时为['bc']
  7. 同理第一次递归里大的for循环后可得到['cb']
  8. 第一次递归也结束,result此时为['bc','cb']
  9. 回到最开始,第一次递归的result给newArr,接着继续推进代码,即可得到['abc','acb']
  10. 然后外层for循环即可得到[ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ]

猜你喜欢

转载自blog.csdn.net/iufesjgc/article/details/111563064