一、斐波那契数列

2023-06-13  本文已影响0人  LucXion
/// 1. 爬楼梯 : 一次只能前进 1 或 2
/// - Parameter step: 台阶数
/// - Returns:
fileprivate func climbStairs(step:Int) -> Int {
    var first,second,res : Int
    if(step <= 0){
        return 0 // 处理异常数据
    }else if(step == 1){
        return 1 // 1阶 固定值
    }else if(step == 2){
        return 2 // 2阶 固定值
    }
    first = 1;second = 2;res = 3 // 初始化变量
    for _ in 3...step {
        // 核心: 到达第n阶只有两种可能, 第n-1阶往前1步,第n-2阶往前2步,所以第n阶的不同方法为第n-1阶与第n-2阶的方法和
        res = first + second
        first = second
        second = res
    }
    return res
}


/// 2.斐波那契数:0,1,1,2,3... 当前数为前两个数之和
/// - Parameter n: <#step description#>
/// - Returns: <#description#>
fileprivate func fib(_ n: Int) -> Int {
    var first,second,res : Int
    if(n <= 0){
        return 0
    }else if(n == 1){
        return 1
    }else if(n == 2){
        return 1
    }
    first = 1;second = 1;res = 2 // 初始化变量
    for _ in 3...n {
        res = first + second
        first = second
        second = res
    }
    return res
}

/// 3.泰波那契数:0,1,1,2,4... 当前数为前n个数之和(这里的n = 3)
/// - Parameter n: <#step description#>
/// - Returns: <#description#>
fileprivate func fib_3(_ n: Int) -> Int {
    var first,second,third,res : Int
    if(n <= 0){
        return 0
    }else if(n == 1){
        return 1
    }else if(n == 2){
        return 1
    }else if(n == 3){
        return 2
    }
    first = 1;second = 1;third = 2;res = 4 // 初始化变量
    for _ in 4...n {
        res = first + second + third
        first = second
        second = third
        third = res
    }
    return res
}

/// 4. 最小花费爬楼梯:每次向前1,2,每节楼梯都有自己的花费
/// - Parameter step: 台阶数数组,元素为每阶花费
/// - Returns: <#description#>
fileprivate func minimumCostClimbStairs(step:[Int]) -> Int{
    if(step.count == 0){
        return 0
    }else if(step.count == 1){
        return 0
    }else if(step.count == 2){
        return min(step[0], step[1])
    }
    let first = step[0]
    let second = step[1]
    /**
     核心:到达n阶有两种方式,从n-1前进1步,或从n-2前进两步
     那么只要取这两种方式的最小值:Min(到n-1的总开销和n-1当前开销 : 到n-2的总开销+n-2的当前开销)
     */
    var sumN_2:Int = 0 // 到n-2的花费
    var sumN_1:Int = 0 // 到n-1的花费
    var cosN_2:Int = first // n-2的花费
    var cosN_1:Int = second // n-1的花费

    for i in 3...step.count {
        let cosN = step[i - 1]
        let sumN = min(cosN_1 + sumN_1, cosN_2 + sumN_2)
        // 完成最后一次交换
        cosN_2 = cosN_1
        sumN_2 = sumN_1
        cosN_1 = cosN
        sumN_1 = sumN
    }
    // 计算最后的结果时,要加上cos
    return min(sumN_2 + cosN_2, sumN_1 + cosN_1);
}

/// 5.最大花费爬楼梯: 增加条件 1.不可以连续爬1阶(相邻),比如 7-8  2.爬不做限制
/// - Parameter step: <#step description#>
/// - Returns: <#description#>
fileprivate func maxCostClimbStairs(step:[Int]) -> Int{
    // 隐藏条件,达到第n阶有三种情况,max(n-1的总花费+n-1阶,n-2的总花费+n-2阶,n-4的总花费+(n-4)阶+n-1阶)
    var sum_1 = 0
    var sum_2 = 0
    var sum_3 = 0
    var sum_4 = 0
    if(step.count == 0){
        return 0
    }else if(step.count == 1){
        sum_4 = step[0]
        return sum_4;
    }else if(step.count == 2){
        sum_3 = max(step[0], step[1]);
        return sum_3;
    }else if(step.count == 3){
        sum_2 = max(step[1], step[0] + step[2]);
        return sum_2;
    }else if(step.count == 4){
        sum_1 = max(step[0] + step[2],step[0] + step[3],step[1] + step[3])
        return sum_1
    }
    
    sum_1 = max(step[0] + step[2],step[0] + step[3],step[1] + step[3])
    sum_2 = max(step[1], step[0] + step[2]);
    sum_3 = max(step[0], step[1]);
    sum_4 = step[0]
    
    var res = 0;
    for i in 4...step.count-1 {
        // 计算两种情况,当前与n-2,当前与n-3,因为不能连续,所以不能与 n-1比
        res = max(sum_2 + step[i], sum_3 + step[i])
        // 其他平移向后
        sum_4 = sum_3
        sum_3 = sum_2
        sum_2 = sum_1
        // 最后替换sum_1
        sum_1 = res;
    }
    
    return max(sum_1, sum_2, sum_3, sum_4)
}

/// 6.删除并添加数,条件:整数数组、元素无序且可能重复,删除一个数后,它的+1、-1将被忽略。先排序、转化为字典,key=值,value=值*重复次数,然后分段处理,不连续的数直接添加,连续的数转化为爬楼梯
/// - Parameter nums: <#nums description#>
/// - Returns: <#description#>
fileprivate func deleteAndEarn(_ nums: [Int]) -> Int {
    // 将数组排序
    let sorts = nums.sorted(by: <)
    // 整合新数组,value对应的是 值 * 出现次数
    var newValues = [Int]()
    var newKeys = [Int]()
    var unit = 0;
    var currentNum = 0;
    for num in sorts {
        if(newKeys.contains(num) == false){
            newKeys.append(num)
        }
        // current初始化
        if(currentNum == 0){
            currentNum = num
        }
        // 如果num在重复
        if(currentNum == num){
            unit += num
        }else {
            // 如果num不再重复,说明是新的元素
            newValues.append(unit)
            unit = num
            currentNum = num
        }
    }
    newValues.append(unit)

    // 遍历,找梯子ladder,如果没有梯子序列,直接可以加,有梯子,就走打家劫舍的方法
    var ladderArr = [Int]()
    var res = 0
    var tempKey = 0
    var tempKeyIndex = 0
    for keyIndex in newKeys.indices {
        let key = newKeys[keyIndex]
        // 初始化
        if(tempKey == 0){
            tempKey = key
            tempKeyIndex = keyIndex
        }else {
            // 如果key与tempNum形成梯子,那么存储到梯子数组
            if(key == tempKey + 1){
                ladderArr.append(tempKeyIndex)
            }else {
                // 梯子结束
                ladderArr.append(tempKeyIndex)
                var paramArr = [Int]()
                for param in ladderArr {
                    paramArr.append(newValues[param])
                }
                res += maxCostClimbStairs(step: paramArr)
                ladderArr.removeAll()
                tempKey = 0
                tempKeyIndex = 0
            }
            tempKey = key
            tempKeyIndex = keyIndex
        }
    }
    if(tempKey != 0){
        ladderArr.append(tempKeyIndex)
    }
    if(ladderArr.count > 0){
        var paramArr = [Int]()
        for param in ladderArr {
            paramArr.append(newValues[param])
        }
        res += maxCostClimbStairs(step: paramArr)
        ladderArr.removeAll()
    }

    return res
}

/**
 fileprivate func maxCostClimbStairs(step: [Int]) -> Int {
     var dp = [Int](repeating: 0, count: step.count + 1)
     if step.count == 0 {
         return 0
     }
     
     for i in 0..<step.count {
         dp[i + 1] = max(dp[i], (i >= 2 ? dp[i - 1] : 0) + step[i])
     }
     
     return dp[step.count]
 }

 fileprivate func deleteAndEarn(_ nums: [Int]) -> Int {
     if nums.isEmpty {
         return 0
     }
     
     let maxValue = nums.max()!
     var values = [Int](repeating: 0, count: maxValue + 1)
     
     for num in nums {
         values[num] += num
     }
     
     return maxCostClimbStairs(step: values)
 }
 */

上一篇 下一篇

猜你喜欢

热点阅读