70. Climbing Stairs---组合C(m,n)的使用,注意int溢出!

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个数
我的思路是采用排列组合的形式,通过分析,可以发现对于n个台阶,我们可以采用1个两步,2个两步。。。n/2个两步的组合,并且针对不同两步组合m,其变化形式有C(m,n-m)种组合。则总的方法可以有C(0,n)+C(1,n-1)+C(2,n-2)+…+C(n/2, n-n/2).因此,要首先设计组合的求取方法combination。具体算法如下:

class Solution {
    public int climbStairs(int n) {
        int numOf2 = n/2;
        int sum = 0;
        for(int m = 0; m <= numOf2; m++){
            sum += combination(m, n-m);
        }
        return sum;
    }
    public long combination(int m, int n){
        long c = 1;    //注意用long
        if(m > n)
            return -1;
        if(m > n-m)
            m = n-m;
        for(int i = 1; i <= m; i++){
            c = c*(n+1-i)/i;
        }
        return c;
    }
}

在该算法中要注意的是对于大数乘法,要采用长整形,否则会溢出,关于溢出的知识点可以看看java int溢出总结
摘取部分如下:
java 类型提升

int型整数相乘并不会进行类型提升(type promotion),在widening conversion(JSL 5.1.2)写到:

If any of the operands is of a reference type, unboxing conversion(JSL 5.1.8) is performed. Then:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.

所以下述语句并不会发生溢出:

byte a = 40;
byte b = 50;
byte c = 100;
int d = a * b / c;

虽然40 50 = 2000已经超过了byte的范围,但是java compile在计算a b之前已经都将它们转换成了int类型了,所以并不会有编译问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值