JavaScript版《剑指offer》刷题(26)字符串的排列

1.题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

2.思路

递归全排列法:
1.递归思想:把大问题转换为若干小问题;
2.n个元素的全排列 = (n-1) 个元素全排列 + 一个元素作为前缀。
3.递归的出口:只有一个元素的全排列,此时排序完成,输出数组。
4.遍历字符串,将每个字符放在第一个元素作为前缀,并将其余元素继续全排列。
5.新建一个isRepeat空对象,用来判断字符是否重复,若重复则跳过排序。

回溯法:
也就是利用树去尝试不同的可能性,不断地去字符串数组里面拿一个字符出来拼接字符串,当字符串数组被拿空时,就把结果添加进结果数组里,然后回溯上一层。(通过往数组加回去字符以及拼接的字符串减少一个来回溯。)

3.代码

递归全排列法:

function Permutation(str) {
    var result = [];
    if (str.length <= 0) {
        return [];
    }
    var sortTemp= "";
    var arr = str.split("");
    result = sortString(arr, sortTemp, []);
    return result;
}

function sortString(arr, sortTemp, res) {
    if (arr.length == 0) {
        res.push(sortTemp);
    } else {
        var isRepeat = {};
        for (var i = 0; i < arr.length; i++) {
            if (!isRepeat[arr[i]]) {
                var temp = arr.splice(i, 1)[0]; // 取出第i个字符
                sortTemp+= temp; // 第i个字符设为前缀
                sortString(arr, sortTemp, res);
                arr.splice(i, 0, temp); // 补全取出的元素,恢复原字符串
                sortTemp= sortTemp.slice(0, sortTemp.length - 1); // 清空sortTemp
                isRepeat[temp] = true;
            }
        }
    }
    return res;
}

回溯法:

// 回溯法
function Permutation(str) {
  let res = [];
  const pStr = '';
  if (str.length <= 0) return res;
  arr = str.split(''); // 将字符串转化为字符数组
  res = permutate(arr, pStr, res);
  return res;
}
function permutate(arr, pStr, res) {
  if (arr.length === 0) {
    return res.push(pStr);
  }
  const isRepeated = new Set();
  for (let i = 0; i < arr.length; i++) {
    if (!isRepeated.has(arr[i])) {
      // 避免相同的字符交换
      const char = arr.splice(i, 1)[0];
      pStr += char;
      permutate(arr, pStr, res);
      arr.splice(i, 0, char); // 恢复字符串,回溯
      pStr = pStr.slice(0, pStr.length - 1); // 回溯
      isRepeated.add(char);
    }
  }

  return res;
}

参考文章:
https://www.cnblogs.com/echovic/p/6529630.html
https://www.cnblogs.com/wuguanglin/p/Permutation.html
https://github.com/DavidChen93/-offer-JS-/blob/master/38.1 字符串的排列.js

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值