zoukankan      html  css  js  c++  java
  • 数据结构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)
    
  • 相关阅读:
    .JS replace方法替换所有字符
    .net framework 4.0,结果还是失败,出现HRESULT 0xc8000222错误代码
    用PowerDesigner15自动将数据库里的表生成ER图
    C#对JSON数据格式的处理
    Type of conditional expression cannot be determined because there is no implicit conversion between 'Common.EnumType.EnumGender' and '<null>'
    如何在string.Format方法中输出大括号({})
    网架构学习笔记
    c#实现javascript中函数escape解码
    Solon 开发,八、注入依赖与初始化
    Solon 开发,七、自定义注解开发汇总
  • 原文地址:https://www.cnblogs.com/gdy1993/p/12984699.html
Copyright © 2011-2022 走看看