每日一練6.26——字符串的排列

題目

字符串的排列

輸入一個字符串,打印出該字符串中字符的所有排列。

你可以以任意順序返回這個字符串數組,但裏面不能有重複元素。

示例:

輸入:s = “abc”
輸出:[“abc”,“acb”,“bac”,“bca”,“cab”,“cba”]

輸入:s = “aab”
輸出:[“aab”, “aba”, “baa”]

限制:1 <= s 的長度 <= 8

思路

兩種思路:

  • 遞歸:第一個位置確定後,後面的n-1個位置的確定就是小規模問題了
  • 回溯:使用全局變量記錄返回結果,內部定義函數來執行回溯操作
# 遞歸
def perm(s):
    if len(s) == 1:  # 邊界
        return [s]
    res = []
    used = set()
    for i in range(len(s)):  # 第一個可選的
        if s[i] in used:  # 剪枝
            continue
        used.add(s[i])
        sub_res = perm(s[:i]+s[i+1:])   
        res.extend([s[i]+p for p in sub_res])
    return all

# 回溯
def perm2(s):
    n = len(s)
    res = []
    def dfs(t, path):   # 深度優先
        if len(path) == n:   # 節點
            res.append(path)
        used = set()
        for i in range(t):   # 可選擇的
            if s[i] in used:  # 剪枝
                continue    
            used.add(t[i])
            path += t[i]    # 入棧
            dfs(t[:i]+t[i+1:], path)
            path -= t[i]    # 出棧
    dfs(s, "")
    return res

代碼實現中注意的點:

  • 使用used進行剪枝
  • 對於列表或者字符串s,len(s)=ns[k],k>=n非法,但是s[k:]是合法的(等於[]或者""
  • 遞歸直接返回求解結果,回溯使用全局變量記錄結果,內部定義函數實現(回溯)操作
  • 遞歸的套路:用小規模的結果構成大規模的結果
  • 回溯的套路:實際上就是樹的前序遍歷
def dfs(path, t):  # path:記錄路徑列表,t:選擇列表
    if path 包含葉子:
        一定的操作
        return
    for i in t:    # 遍歷選擇列表
        path.append(i)  # 進行選擇
        dfs(path, t_next)     # 對子節點進行遍歷
        path.pop()    # 撤銷選擇
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章