每日一练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()    # 撤销选择
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章