Leetcode - 全排列

题目描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

在这里插入图片描述

示例 1:

输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]

class Solution(object):
    num2str = {2: "abc", 3: "def", 4: "ghi", 5: "jkl", 6: "mno", 7: "pqrs", 8: "tuv", 9: "wxyz"}
    ans_list = []
    ans = []
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        self.ans_list.clear()
        if len(digits) == 0:
            return []
        self.DFS(digits, 0)
        return self.ans_list

    def DFS(self, s, begin):
        if begin >= len(s): ##ans_list.append
            self.ans_list.append("".join(self.ans))
            return
        else:
            digit = int(s[begin])
            for i in self.num2str[digit]:
                self.ans.append(i)
                self.DFS(s,begin+1)
                self.ans.pop()##回溯

其实这和全排列是一样的!下面来看一下全排列应该如何做。

题目描述

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]

class Solution(object):
    ans_list = []
    ans = []
    visit = None
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        self.ans_list = []
        self.visit = [0] * len(nums) ###不能重复访问!!
        self.DFS(nums,0)
        return self.ans_list
    def DFS(self, num_list, begin):
        if(begin>=len(num_list)):
            print(self.ans)
            self.ans_list.append(self.ans[:])
            return
        for i in range(len(num_list)):
            if self.visit[i] == 0:  ###hasn't visited yet
                self.visit[i] = 1
                self.ans.append(num_list[i])
                self.DFS(num_list,begin+1)
                self.ans.pop()
                self.visit[i] = 0

❗❗ 注意

  1. self.ans_list.append(self.ans[:]), 必须要加上self.ans [:]
  2. 当出现不能重复的要求时,应该用一个数组visited来记录是否被访问过。

在这里插入图片描述

题目描述

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

思路

和全排列一样,考虑每一步应该落哪一个值。对左括号和右括号分别有一个计数,当左括号的个数<需要括号个数的时候,可以添加一个左括号;当右括号个数<左括号时,可以增加一个右括号。

class Solution(object):
    ans_list = list()
    ans = ""
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        self.ans_list = [] ##重置
        self.DFS(n, 0, 0, 0)
        return self.ans_list
    def DFS(self,pair_num, left_num, right_num, index):
        if (index == pair_num*2) and (left_num == right_num):
            self.ans_list.append(self.ans)
            return
        if left_num < pair_num:
            self.ans+="("
            self.DFS(pair_num,left_num+1,right_num,index+1)
            self.ans = self.ans[:-1]
        if right_num < left_num:
            self.ans+=")"
            self.DFS(pair_num, left_num, right_num+1, index + 1)
            self.ans = self.ans[:-1]

❗ 注意
index == pair_num*2时停止,而不是index == pair_num*2-1,这是因为只有index出界的时候才需要停止,在最后一位的时候不需要停止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值