zoukankan      html  css  js  c++  java
  • 剑指offer第9题

    解题思路一

    /**
     * 目标:
     * 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
     * 求该青蛙跳上一个n级的台阶总共有多少种跳法。
     * 思路:
     * 因为是n级台阶,第一步有n种跳法:跳1、2、3。。。n级
     * 第一步:
     * 跳1级,剩下n-1级,则剩下的跳法是f(n-1)
     * 跳2级,剩下的跳法是f(n-2)
     *
     * 。。。。
     *
     * 跳n级,剩下的跳法是f(0),所以一次跳n级只有1种方式
     * 因此
     * f(n)= f(n-1)+f(n-2)+。。。+f(1)+1
     * f(n-1)= f(n-2)+。。。+f(1)+1
     * 所以
     * f(n)= 2*f(n-1)
     *
     */
    public class Sulution9 {
        public int JumpFloorII(int target) {
            if (target==1){
                return 1;
            }
            if (target==2){
                return 2;
            }
            int result = 1;
            for (int i = 1; i < target; i++) {
                result = result*2;
            }
            return result;
        }
    }

    解题思路二

    可以尝试用动态规划的思想

    了解动态规划

    动态规划的判断步骤:

    1、是否含有最优子结构

    即一个问题的最优解依赖与它所有子问题的解.

    对于这道题,由于情况可以选择跳一级,也可以选择跳两级...选择跳n级,所以青蛙到达第n 级的台阶有n种方式

    • 一种是从第n-1 级跳上来
    • 一种是从第n-2 级跳上来
    • ....
    • 从第n级跳上来

    第n级台阶的最优解依赖于各个子问题最优解的和,即:

    f(n) = f(n-1)+f(n-2)+...+f(1)+f(0)

    2、是否含有重叠子问题

    跳到第n-1阶的最优解同样依赖于各个子问题的最优解的和,并且可以类推.

    因此这是一个动态规划问题.

    动态规划的解题步骤:

    1、定义数组元素间的含义

    我们以dp[n]表示跳到第n级台阶的所有可能性,即跳上一个n级的台阶总共有 dp[n] 种跳法

    2、找出数组元素间的关系

    就是把一个规模比较大的问题分成几个规模比较小的问题,然后由小的问题推导出大的问题。也就是说,dp[n] 的规模为 n,比它规模小的是 n-1, n-2, n-3…. 也就是说,dp[n] 一定会和 dp[n-1], dp[n-2]….存在某种关系的。因此要找出他们的关系。

    • 一种是从第n-1 级跳上来
    • 一种是从第n-2 级跳上来
    • ....
    • 从第0级跳上来

    由于我们是要算所有可能的跳法的,所以有

    dp[n] = dp[n-1] + dp[n-2]+....+dp[0]

    而:

    dp[n-1] = dp[n-2] + dp[n-3]+....+dp[0]

    因此我们知道:

    dp[n] = 2 * dp[n-1]

    3、找出初始值

    当n = 1 时,dp[1] = dp[0] + dp[-1],而我们是数组是不允许下标为负数的,所以对于 dp[1],我们必须要直接给出它的数值,相当于初始值,显然,dp[1] = 1。一样,dp[0] = 0.(因为 0 个台阶,那肯定是 0 种跳法了)。于是得出初始值:

    dp[0] = 0;
    dp[1] = 1;

    代码:

    public int JumpFloorII(int target) {
            if (target<0){
                return target;
            }
            //定义数组含义
            int[] dp = new int[target+1];
            //找到初始值
            dp[0] = 0;
            dp[1] = 1;
            for (int i = 2; i < target+1; i++) {
                //找到数组元素间的关系
                dp[i] = 2*dp[i-1];
            }
            return dp[target];
        }
  • 相关阅读:
    测试Remoting服务端和客户端的双向通信
    对T4模板研究针对SQL SERVER的EF代码生成
    菜鸟级WinForm分页控件
    [小技术应用]框架下动态调用用户控件的模态弹出窗体
    根据数据库表动态添加菜单及打开窗体
    Windows Mobile 5.0下蓝牙移动打印测试
    Window Mobile/CE的PC端安装测试
    基于Dev控件,在WinForm下动态配置界面
    TortoiseSVN使用简介
    SQL的一些经典算法
  • 原文地址:https://www.cnblogs.com/Adam-Ye/p/13451652.html
Copyright © 2011-2022 走看看