【Leetcode】62. Unique Paths(配数学证明)

题目地址:

https://leetcode.com/problems/unique-paths/

给定一个 p × q p\times q p×q的二维矩阵,问从 ( 0 , 0 ) (0,0) (0,0)出发至右下角有多少个路径。每个路径只允许向右或者向下走。

一共要走 p + q − 2 p+q-2 p+q2步,其中 p − 1 p-1 p1步是向下。设 m = p − 1 , n = q − 1 m=p-1, n=q-1 m=p1,n=q1,由组合数学知,路径数等于 ( m + n m ) = ( m + n ) ! m ! n ! {m+n\choose m}=\frac{(m+n)!}{m!n!} (mm+n)=m!n!(m+n)!,直接代入公式计算即可。需注意这里要用long,否则乘积会越界。另外还有一点要注意的是,如果直接算 ( m + n ) ! (m+n)! (m+n)!仍然会溢出。不妨设 m ≥ n m\ge n mn,那么其实是算 ( m + n ) ( m + n − 1 ) . . . ( m + 1 ) n ( n − 1 ) . . . 1 \frac{(m+n)(m+n-1)...(m+1)}{n(n-1)...1} n(n1)...1(m+n)(m+n1)...(m+1)之所以要这样算是为了让分子尽量小,从而减少溢出的可能性。但是这样仍然会溢出。由于组合数总是整数,而上式对于任意的 n n n都是整数,从而我们可以边乘边除,每次乘以 m + n − k m+n-k m+nk后就除以 k + 1 k+1 k+1 k k k 0 0 0取到 n − 1 n-1 n1,而由于对任意的 n n n上面的分式总是整数,从而这样计算的时候不会出现除以 k + 1 k+1 k+1不整除的情况,这样就最大程度避免了溢出。代码如下:

class Solution {
 public:
  using ll = long long;
  int uniquePaths(int m, int n) {
    m--, n--;
    ll res = 1;
    int k = min(m, n);
    for (int i = 0; i < k; i++) {
      res *= m + n - i;
      // 这里是不会除不尽的,见上面的解释
      res /= i + 1;
    }
    return (int)res;
  }
};

时间复杂度 O ( min ⁡ { m , n } ) O(\min\{m,n\}) O(min{m,n}),空间 O ( 1 ) O(1) O(1)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值