• 数据结构python实现(二)递归


    (二)递归

    1. 什么样的问题能够用递归来解决

    递归需要满足三个条件:

    (1)一个问题的解可以分解成几个子问题的解
    
    (2)这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样	
    
    (3)存在递归终止条件
    

    写递归代码的关键也是,找到递推公式和终止条件

    1. 案例

    案例1 阶乘

    #循环实现
    #时间O(n)
    #空间O(1)
    def factorial(n):
        result = 1
        for i in range(1, n+1):
            result *= i
        return result
      
    #递归实现
    #时间O(n)
    #空间O(n)
    ef factorial_recursive(n):
        if n == 1:
            return 1
        return n * factorial_recursive(n - 1)
    

    案例2 斐波那契数列

    #递归实现
    #时间O(2^n)
    def fibonacci1(n):
        assert(n>0)
        if (n <= 2): 
            return 1
        return fibonacci2(n-1) + fibonacci2(n-2)
      
      #循环实现
      #时间O(n)
      def fibonacci2(n):
        assert(n>0)
        a,b=0,1
        for i in range(1,n+1):
          a,b=b,a+b
        return a
      
      def fibonacci3(n):
        assert(n>0)
        if (n <= 1): 
            return (n,0)
        (a, b) = fibonacci3(n-1)
        return (a+b, a)
    

    案例3 打印尺子

    (热身)打印一下内容:

    1

    1 2 1

    1 2 1 3 1 2 1

    1 2 1 3 1 2 1 4 1 2 1 3 1 2 1

    #时间O(2^n)
    def ruler_bad(n):
        assert(n>=0)
        if (n==1):
            return "1"
        return ruler(n-1) + " " + str(n) + " " + ruler(n-1)
    
    #时间O(n)
    def ruler(n):
        assert(n>=0)
        if (n==1):
            return "1"
        t = ruler(n-1)
        return t + " " + str(n) + " " + t
    
    #循环实现
    def ruler2(n):
        result = ""
        for i in range(1, n+1):
            result = result + str(i) + " " + result
        return result
    

    画尺子:

    #画横线
    def draw_line(tick_length, tick_label=''):
        line = '-' * tick_length
        if tick_label:
            line += ' ' + tick_label
        print(line)
    #画每一个大格子    
    def draw_interval(center_length):
        if center_length > 0:
            draw_interval(center_length - 1)
            draw_line(center_length)
            draw_interval(center_length - 1)
    #画多个格子    
    def draw_rule(num_inches, major_length):
        draw_line(major_length, '0')
        for j in range(1, 1 + num_inches):
            draw_interval(major_length - 1)
            draw_line(major_length, str(j))
    

    案例4 数字表达式

    Given two integers a ≤ b, write a program that transforms a into b by a minimum sequence of increment (add 1) and unfolding (multiply by 2) operations.

    For example,

    23 = ((5 * 2 + 1) * 2 + 1)

    113 = ((((11 + 1) + 1) + 1) * 2 * 2 * 2 + 1)

    def intSeq(a, b):
        if (a == b):
            return str(a)
        
        if (b % 2 == 1):
            return "(" + intSeq(a, b-1) + " + 1)"
        
        if (b < a * 2):
            return "(" + intSeq(a, b-1) + " + 1)"
            
        return intSeq(a, b/2) + " * 2";
    

    案例5 汉诺塔

    def hanoi(n, start, end, by):
        if (n==1):
            print("Move from " + start + " to " + end)
        else:
            hanoi(n-1, start, by, end)
            hanoi(1, start, end, by)
            hanoi(n-1, by, end, start)
    

    格雷码

    def moves_ins(n, forward):
        if n == 0:
            return
        moves_ins(n-1, True)
        print("enter ", n) if forward else print("exit  ", n)
        moves_ins(n-1, False)
    

    案例6 subset

    返回一个集合的所有子集

    实现1:

    def subsets(nums):
        result = [[]]
        for num in nums:
            for element in result[:]:
                x=element[:]
                x.append(num)
                result.append(x)
            
        return result
    

    实现2(回溯):

    def subsets_recursive(nums):
        lst = []
        result = []
        subsets_recursive_helper(result, lst, nums, 0);
        return result;
    
    def subsets_recursive_helper(result, lst, nums, pos):
        result.append(lst[:])
        for i in range(pos, len(nums)):
            lst.append(nums[i]) #
            subsets_recursive_helper(result, lst, nums, i+1) #
            lst.pop()
    

    案例7 subsets2

    Given a collection of integers that might contain duplicates, nums, return all possible subsets.

    def subsets2(nums):
        res = [[]]
        for num in nums: 
            res += [ i + [num] for i in res if i + [num] not in res]
        return res
    
    def subsets_recursive2(nums):
        lst = []
        result = []
        nums.sort()
        print(nums)
        subsets2_recursive_helper(result, lst, nums, 0);
        return result;
    
    def subsets2_recursive_helper(result, lst, nums, pos):
        result.append(lst[:])
        for i in range(pos, len(nums)):
            if (i != pos and nums[i] == nums[i-1]):
                continue;
            
            lst.append(nums[i])
            subsets2_recursive_helper(result, lst, nums, i+1)
            lst.pop()
    

    案例8 Permutation

    Given abc:

    Output: bca cba cab acb bac abc

    def perm(result, nums):
        if (len(nums)==0):
            print(result)
    
        for i in range(len(nums)):
            perm(result+str(nums[i]), nums[0:i]+nums[i+1:])
    

    案例9 Permutation Unique

    def permUnique(result, nums):
        nums.sort()
        if (len(nums)==0):
            print(result)
        for i in range(len(nums)):
            if (i != 0 and nums[i] == nums[i-1]):
                continue;
            permUnique(result+str(nums[i]), nums[0:i]+nums[i+1:])
    
    def permuteUnique(nums):
        ans = [[]]
        for n in nums:
            new_ans = []
            for l in ans:
                for i in range(len(l)+1):
                    new_ans.append(l[:i]+[n]+l[i:])
                    if i<len(l) and l[i]==n: break              #handles duplication
            ans = new_ans
        return ans
    
    

    案例10 Permutation of Size K

    takes two parameters n and k, and prints out all P(n, k) = n! / (n-k)! permutations that contain exactly k of the n elements. when k = 2 and n = 4

    ab ac ad ba bc bd ca cb cd da db dc

    def permSizeK(result, nums, k):
        if k == 0:
            print(result)
        for i in range(len(nums)):
            permSizeK(result+str(nums[i]), nums[0:i] + nums[i+1:], k - 1)
    

    案例11 Letter Case Permutation

    Enumerate all uppercase/lowercase permutation for any letter specified in input

    For example,

    word = “medium-one”Rule = “io”

    solutions = [“medium-one”, “medIum-one”, “medium-One”, “medIum-One”]

    results = set()
    keys = set()
    
    def permLetter(word, rule):
        rule = rule.lower()
        for c in rule:
            keys.add(c)
        permHelper(word, rule, 0, "")
        
    def permHelper(word, rule, index, prefix):
        length = len(word)
        
        for i in range(index, length):
            c = word[i]
            if (c in keys):
                permHelper(word, rule, i + 1, prefix + c)
                
                c = c.upper()
                permHelper(word, rule, i + 1, prefix + c)
            else:
                prefix += c
        
        if (len(prefix) == len(word)):
            results.add(prefix)    
    

    案例12 Combination Sum

    Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

    The same repeated number may be chosen from candidates unlimited number of times.

    def comb(nums, t):
        result = []
        tmp = []
        combHelper(result, tmp, nums, t, 0)
        return result
            
    def combHelper(result, tmp, nums, remains, start):
        if remains < 0: return
        if remains == 0:
            result.append(tmp[:])
        else:
            for i in range(start, len(nums)):
                tmp.append(nums[i])
                combHelper(result, tmp, nums, remains - nums[i], i)
                tmp.pop()
    

    案例13 Combination Sum II

    Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

    Each number in candidates may only be used once in the combination.

    Note:

    All numbers (including target) will be positive integers.

    The solution set must not contain duplicate combinations.

    def comb2(nums, t):
        result = []
        tmp = []
        nums.sort()
        combHelper2(result, tmp, nums, t, 0)
        return result
            
    def combHelper2(result, tmp, nums, remains, start):
        if remains < 0: return
        if remains == 0:
            result.append(tmp[:])
        else:
            for i in range(start, len(nums)):
                if(i > start and nums[i] == nums[i-1]): continue; # skip duplicates
                tmp.append(nums[i])
                combHelper2(result, tmp, nums, remains - nums[i], i + 1)
                tmp.pop()
    

    案例14 Parentheses

    Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

    def generateParenthesis(n):
        def generate(prefix, left, right, parens=[]):
            if right == 0:   parens.append(prefix)
            if left > 0:     generate(prefix + '(', left-1, right)
            if right > left: generate(prefix + ')', left, right-1)
            return parens
        return generate('', n, n)
    
  • 相关阅读:
    redis 操作
    Xcode 改时间问题 lua代码没反应问题
    apk 反编译
    mysql远程连接命令
    python 利用三方的xlrd模块读取excel文件,处理合并单元格
    eclipse 新建项目不可选择Java Project 解决方法
    eclipse左边的工程列表窗口不见了解决方案
    python_pycham,连接数据库,执行sql
    Eclipse修改默认的语言编码设置,处理乱码
    httprunner中的分层(api、testcase、testsuite)及实际使用
  • 原文地址:https://www.cnblogs.com/gdy1993/p/12984699.html
Copyright © 2020-2023  润新知