剑指Offer 38 - 字符串的排列

题目描述

输入一个字符串,打印出该字符串中字符的所有排列。你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

(PS:字符串中可能有重复元素)

思路

每次遍历一遍整个数组,选择一个还没有被排列的字母。由于给定字符串中可能含有重复字母,应当用Set来存储排列序列,避免重复。

s为给定字符串,used数组记录使用过的字母,cur记录当前排列的序列,res为最终返回的集合(Set):

递归退出条件:cur数组长度与s相同,将cur加入res,返回上一层递归。

递推工作:

  1. 遍历每一个字母,如果used[i]被标记过,跳过,否则将其加入cur,并在used数组中标记。
  2. 进入下一层递归
  3. 从cur中删除刚才加入的字母,抹除used标记,返回上一层递归。

代码:

/**
 * @param {string} s
 * @return {string[]}
 */
var permutation = function(s) {
    if(!s.length)  return [""];
    
    const len = s.length;
    let cur = [];
    let used = [];
    let res = new Set();
    dfs();
    return Array.from(res);
    
    function dfs(){
        if(cur.length === len){
            res.add(cur.join(''));
            return;
        }
        
        for(let i = 0; i < len; i++){
            if(used[i]) continue;
            used[i] = true;
            cur.push(s.charAt(i));
            dfs();
            cur.pop();
            used[i] = false;
        }
        
    }
};

易错:

  1. 将cur数组合成字符串时不能用toString(),否则得到的字符串含有“,”
  2. Set添加元素方法为add
  3. 题目要求最终返回string数组,return时要用Array.from将Set转换为数组

猜你喜欢

转载自www.cnblogs.com/xintangchn/p/13202076.html