暴力递归(一)(python实现)

1、汉诺塔问题

  打印n层汉诺塔从左到右边的全部过程

class Solution:
    def hano(self, n):
        if n > 0:
            self.move(n, "", "", "")

    def move(self, i, start, end, other):
        # start:左   end:右   other:中
        if i == 1:  # 如果只有一层,直接移到最右边
            print("move 1 from " + start + " to " + end)

        else:   # 如果超过一层
            self.move(i - 1, start, other, end) # 先将前n-1层借助右边移到中间
            print("move " + str(i) + " from " + start + " to " + end)   #将最后一层移到右边
            self.move(i - 1, other, end, start) # 再讲中间的n-1层借助左边移到右边

 

2、打印一个字符串的全部子序列

class Solution:
    def printList(self, str):
        res = []
        if str:
            strList = list(str)
            self.process(strList, 0, res)


    def process(self, strList, i, res):
        if i == len(strList):
            print("".join(res))
            return
        resKeep = res.copy()
        resKeep.append(strList[i])
        self.process(strList, i+1, resKeep)  # 保留当前字符
        resNoKeep = res.copy()  #不保留当前字符
        self.process(strList,i+1, resNoKeep)

 

3、打印一个字符串的全部排列

  1)打印一个字符串的全部排列

  

class Solution:
    def printAllArray(self, str):
        res = []
        if str:
            strList = list(str)
            self.process(strList, 0, res)

        return res

    def process(self, strList, i, res):
        if i == len(strList):
            res.append("".join(strList))
            # 注意,如果写成:
            # res.append(strList) 最终,res里面的结果是一样的,相当于引用
            # res.append(strList[:]) 相当于copy
        for j in range(i, len(strList)):
            strList[i], strList[j] = strList[j], strList[i] # 交换i位置后两字符顺序,继续进行
            self.process(strList, i+1, res)
            strList[i], strList[j] = strList[j], strList[i] # 返回原状态

 

  2)打印一个字符串的全部排列,要求不能出现重复排列

  可以使用上面代码,最终用set去重,或者分支限界,如下:

class Solution:
    def printAllArray2(self, str):
        res = []
        if str:
            strList = list(str)
            self.process_de_duplication(strList, 0, res)

        return res

    def process_de_duplication(self, strList, i, res):
        if i == len(strList):
            res.append("".join(strList))
            # 注意,如果写成:
            # res.append(strList) 最终,res里面的结果是一样的,相当于引用
            # res.append(strList[:]) 相当于copy

        visit = dict((i, False) for i in strList) # 检测当前字符是否访问过
        for j in range(i, len(strList)):
            if not visit[strList[j]]:
                visit[strList[j]] = True
                strList[i], strList[j] = strList[j], strList[i]  # 交换i位置后两字符顺序,继续进行
                self.process_de_duplication(strList, i + 1, res)
                strList[i], strList[j] = strList[j], strList[i]  # 返回原状态

 

4、给定一个字符串S,通过将字符串S中的每个字母转变大小写,获得一个新的字符串。返回所有可能得到的字符串集合。

class Solution:
    def letterCasePermutation(self, S):
        if len(S) == 0:
            return []

        res = []
        path = []
        self._dfs(S, 0, path, res)
        return res

    def _dfs(self, S, index, path, res):
        if index == len(S):
            res.append("".join(path))
            return res

        path.append(S[index])
        self._dfs(S, index + 1, path, res)
        path.pop()

        if S[index].isalpha():
            path.append(chr(ord(S[index]) ^ (1 << 5)))
            self._dfs(S, index + 1, path, res)
            path.pop()

 

5、不申请额外的数据结构,只使用递归,逆序一个栈

  参考

  1)首先,设计函数: int getAndRemovTailElement(…)。如下图所示:
在这里插入图片描述
    2) 其次,设计递归函数: stackReverse(…),该函数将调用上述函数,最终完成一个栈的逆序。如下图所示:
在这里插入图片描述

 

class Solution:
    def stackReverse(self,stack):
        if stack.isEmpty():
            return
        i = self.getAndRemoveTailElement(stack)
        self.stackReverse(stack)
        stack.push(i)

    def getAndRemoveTailElement(self,stack):
        result = stack.pop()
        if stack.isEmpty():
            return  result
        else:
            last = self.getAndRemoveTailElement(stack)
            stack.push(result)
            return last

 

posted @ 2020-05-13 11:41  r1-12king  阅读(312)  评论(0)    收藏  举报