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)
    
  • 相关阅读:
    C++预备知识
    C++求最小公倍数
    c++编写函数,递归删除字符串中的子串,求删除次数
    ERROR 1452 : Cannot add or update a child row: a foreign key constraint fails
    django快速搭建blog
    北邮 北理 人大经验
    C、C++、Java语言中异常处理机制浅析
    学习git部署
    各种符号的使用情况说明以及区别
    【转】通过fio工具,测试SATA,SAS,SSD 读写性能
  • 原文地址:https://www.cnblogs.com/gdy1993/p/12984699.html
Copyright © 2011-2022 走看看