70. Climbing Stairs

89 阅读2分钟

题目描述

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

解题思路: 递归法

这是一个经典的递归题目, 我们可以找到递归的条件: 上n层楼梯的方法等于 n-1层的方法 + n-2层的方法, 这样, 再加上一些边缘判断,我们就可以写出代码
时间复杂度: O(n(n-1))

示例代码

func climbStairs(_ n: Int) -> Int {
    if n <= 3 {
        return n
    }
    return climbStairs(n-2) + climbStairs(n-1)
}

上边的思路我们可以很简单的得到算法, 但是这个代码存在一个问题,就是当我们计算6(n)的时候, 我们计算过一次5(n-1), 计算7(n+1)的时候, 又会计算一次5(n-2),这样我们就会多出一倍的计算量, 我们可以对此进行优化! 使用一个数组,记录一下计算过的值, 没有计算过的才进行计算
时间复杂度: O(n)

示例代码

func climbStairs(_ n: Int) -> Int {
    if n <= 3 {
        return n
    }
    var tempArr = Array(repeating: 0, count: n+1)
    tempArr[1] = 1
    tempArr[2] = 2
    tempArr[3] = 3
    climb(n, &tempArr)
    return tempArr[n]
}

func climb(_ n: Int, _ tempArr: inout [Int]) {
    let n1 = n - 1
    let n2 = n - 2
    if n1 > 2 && tempArr[n1] == 0 {
        climb(n1, &tempArr)
    }
    if n2 > 2 && tempArr[n2] == 0 {
        climb(n2, &tempArr)
    }
    tempArr[n] = tempArr[n-1] + tempArr[n-2]
}

根据上边的思路,我们使用数据记录了之前计算过的值, 所以,我们可以直接一个数组的遍历,来实现递归
时间复杂度: O(n)

示例代码

func climbStairs(_ n: Int) -> Int {
    if n <= 3 {
        return n
    }
    var tempArr = Array(repeating: 0, count: n+1)
    tempArr[1] = 1
    tempArr[2] = 2
    tempArr[3] = 3
    for n in 3...n {
        tempArr[n] = tempArr[n-1] + tempArr[n-2]
    }

    return tempArr[n]
}