JZ27 字符串的排列

字符串的排列

輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則按字典序打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。

輸入描述: 輸入一個字符串,長度不超過9(可能有字符重複),字符只包括大小寫字母。

思路:

對於一個長度爲 nn 的字符串(假設字符互不重複),其排列方案數共有:n×(n−1)×(n−2)…×2×1

排列方案的生成:根據字符串排列的特點,考慮深度優先搜索所有排列方案。即通過字符交換,先固定第 11 位字符( nn 種情況)、再固定第 22 位字符( n-1n−1 種情況)、... 、最後固定第 nn 位字符( 11 種情況)。

當字符串存在重複字符時,排列方案中也存在重複的排列方案。爲排除重複方案,需在固定某位字符時,保證 “每種字符只在此位固定一次” ,即遇到重複字符時不交換,直接跳過。從 DFS 角度看,此操作稱爲 “剪枝” 。

func Permutation(s string) []string {
    var ans []string
    newStr := make([]string, len(s))
    for k, v := range s {
        newStr[k] = string(v)
    }
    sort.Strings(newStr)
    n := len(s)
    perm := ""
    vis := make([]bool, n)
    var backtrack func(int)
    backtrack = func(idx int) {
        if idx == n {
            ans = append(ans, perm)
        }
        for i, v := range newStr {
            if vis[i] || i > 0 && !vis[i-1] && v == newStr[i-1] {
                continue
            }
            perm += v
            vis[i] = true
            backtrack(idx + 1)
            vis[i] = false
            perm = perm[:len(perm)-1]
        }
    }
    backtrack(0)
    return ans
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章