• LeetCode Easy: 70. Climbing Stairs


    一、题目

    You are climbing a stair case. It takes n steps to reach to the top.

    Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

    Note: Given n will be a positive integer.

    Example 1:

    Input: 2
    Output:  2
    Explanation:  There are two ways to climb to the top.
    
    1. 1 step + 1 step
    2. 2 steps

    Example 2:

    Input: 3
    Output:  3
    Explanation:  There are three ways to climb to the top.
    1. 1 step + 1 step + 1 step
    2. 1 step + 2 steps
    3. 2 steps + 1 step
    爬楼梯,每次只能爬一步或者两步,看一共有多少爬法。

    二、思路
    首先肯定能用递归来计算,到达第 i 个位置时,都有两种选择,爬一步(此时可以表示成 i - 1 位置上然后上一步),或者爬两步(此时可以看成 i - 2 位置然后跨两步),所以此问题到达第 i 个位置可能
    的结果可以表示成第 i - 1 位置上的结果 + i - 2 位置上的结果。跟斐波那契数列一样。所以代码可以这样写:
    def climbStairs2(n):
        if n == 1:
            return 1
        elif n == 2:
            return 2
        else:
            print(climbStairs2(n-1)+climbStairs2(n-2))
            return climbStairs2(n-1)+climbStairs2(n-2)
    但是递归一般是像我这样的菜鸡才用的,高手一般都不用递归,有点慢,会重复计算很多之前计算过的步骤。于是我花了点时间学习了动态规划,其实我感觉相比较递归,动态规划就是把递归过程中的子问题的解
    集用一个数组保存下来,以备后用,整体上我感觉跟递归的差距就在这里了,同样也是把一个大问题分成好多小问题,然后解决每一个小问题的最优解,最后汇集。这是我的观点,由于接触时间比较短,有说错的
    地方还请大神提点。
    动态规划的代码如下,用三个变量保存结果:
    def climbStairs(n):
        """
        :type n: int
        :rtype: int
        """
        n_1 = 1
        n_2 = 0
        for i in range(1,n+1):
            tmp = n_1+n_2
            n_2 = n_1
            n_1 = tmp
        print(tmp)
        return tmp
    

    学习动态规划的一些例子和代码如下:

    #coding:utf-8
    import numpy as np
    def climbStairs(n):
        """
        :type n: int
        :rtype: int
        """
        n_1 = 1
        n_2 = 0
        for i in range(1,n+1):
            tmp = n_1+n_2
            n_2 = n_1
            n_1 = tmp
        print(tmp)
        return tmp
    
    """
    给定一个数组,每次取出来的必须不相邻,求出能取出来的数加起来最大
    """
    #1递归做法
    def rec_opt(arr,i):
        if i == 0:
            return arr[0]
        elif i ==1:
            return max(arr[0],arr[1])
        else:
            A = rec_opt(arr,i-2)+arr[i]
            B = rec_opt(arr,i-1)
            print(max(A,B))
            return max(A,B)
    
    #2、非递归做法
    def dp_opt(arr):
        opt = np.zeros(len(arr))
        opt[0] = arr[0]
        opt[1] = max(arr[0],arr[1])
        for i in range(2,len(arr)):
            A = opt[i-2]+arr[i]
            B = opt[i-1]
            opt[i] = max(A,B)
        print(opt[len(arr)-1])
        return opt[len(arr)-1]
    
    """
    arr={3,34,4,12,5,2} S = 9,均为正整数
    如果arr中存在数据加起来等于S,就返回true,否则flase
    对于每个数都有两种可能,选或者不选
    """
    #1、递归做法
    def rec_subset(arr,i,s):
        if s == 0:
            return True
        elif i == 0:
            return arr[0] == s
        elif arr[i] > s:
            return rec_subset(arr,i-1,s)
        else:
            A = rec_subset(arr,i-1,s-arr[i])
            B = rec_subset(arr,i,s-arr[i])
            print(A or B)
            return A or B
    
    #2、非递归其实就是用数组保存重叠的子问题
    def dp_subset(arr,S):
        subset = np.zeros((len(arr),S+1),dtype=bool)
        subset[:,0] = True
        subset[0,:] = False
        subset[0,arr[0]] = True
        for i in range(1,len(arr)):
            for s in range(1,S+1):
                if arr[i] > s:
                    subset[i,s] = subset[i-1,s]
                else:
                    A = subset[i-1,S-arr[i]]
                    B = subset[i-1,s]
                    subset[i,s] = A or B
        r,c = subset.shape
        print(subset[r-1,c-1])
        return subset[r-1,c-1]
    
    def climbStairs2(n):
        if n == 1:
            return 1
        elif n == 2:
            return 2
        else:
            #print(climbStairs2(n-1)+climbStairs2(n-2))
            return climbStairs2(n-1)+climbStairs2(n-2)
    
    
    
    if __name__ == '__main__':
        #climbStairs2(4)
        climbStairs(4)
        arr = [1,2,4,1,7,8,3]
        arr1 = [4,1,1,9,1]
        arr2 = [3,34,4,12,5,2]
        #rec_opt(arr,6)   #出现很多重叠子问题,采用递归会很慢
        #dp_opt(arr)
        #rec_subset(arr2,len(arr2)-1,9)
        #dp_subset(arr2,12)
    


    既然无论如何时间都会过去,为什么不选择做些有意义的事情呢
  • 相关阅读:
    Navicat 回复 psc 文件 Mysql
    android SDK 更新问题完美解决 http://dl-ssl.google.com refused
    利用android来赚钱
    苹果应用 Windows 申请 普通证书 和Push 证书 Hbuilder 个推(2)
    苹果应用 Windows 申请 普通证书 和Push 证书 Hbuilder 个推
    Java version 32转64位
    浅谈Jquery中的bind()、live()、delegate()、on()绑定事件方式
    JavaScript之深浅拷贝
    关于一道JS面试题的思考
    EasyUI-Tooltip(提示框)学习
  • 原文地址:https://www.cnblogs.com/xiaodongsuibi/p/8681816.html
Copyright © 2020-2023  润新知