1. 程式人生 > 實用技巧 >劍指Offer 38 - 字串的排列

劍指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轉換為陣列