[每日算法] leetcode第62题 Unique Paths

原题目描述

A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).

How many possible unique paths are there?
Above is a 7 x 3 grid. How many possible unique paths are there?
Above is a 7 x 3 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

Example 1:

Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Right -> Down
2. Right -> Down -> Right
3. Down -> Right -> Right

Example 2:

Input: m = 7, n = 3
Output: 28

题目大意

对该题进行简化表述就是:有一个简单的矩阵起点为左上角,终点为右下角,每次行进只能向下或者向右,问有多少条从起点到终点的路径输入为矩阵的行数和列数,输出为路径数量

解题思路

该题目可以采用分治算法,每走到矩阵的一个点,我们都有两种走法,向下或者向右,而当走到矩阵的边界,右边界或者下边界,我们就能确定一条唯一路(因为接下来你只能走同一个方向了),所以采用函数递归,我们可以得到如下代码(此代码不能通过):

int uniquePaths(int m, int n) {
     if (m == 1 || n == 1)   // 到达边界点
         return 1
     // 未到达边界点,向两个方向继续递归
 	 return uniquePaths(m-1, n) +  uniquePaths(n-1, m);
}

该代码使用了尾递归的形式,因为向右和向下的步数是有限的,分别为m-1,和 n-1,所以我们每到一个非边界点,便向这两个方向行进(返回往这两个方向行进到达终点的路径之和),对应的步数-1,当m或n为1时,说明我们到达了某一边界点,这时也确定了一条唯一的路径,返回1。
然而,该代码虽然正确,但并不完善,当m,n的值过大时会造成TL,因为会造成冗余的计算,如到达(m = 10, n = 10)的点,那么接下来,我们会到达(m = 9, n = 10)和 (m = 10, n = 9),而这两个点后边都会经过(m = 9, n = 9)的点,那么我们会计算两次uniquePaths(9, 9),而越到底部,这样重复的计算就会越多,最终造成运算时间过大
所以我们需要把这些计算得到的值存起来,下次如果需要使用这些值,无需再次计算,就直接得到该值,便能大大减少运算时间了。实现代码如下:

C++实现代码

// 二维数组用来存储点(m, n)到达终点的路径数,初始均为0
int a[101][101] = {};

class Solution {
public:
  int uniquePaths(int m, int n) {
      if (m == 1 || n == 1)  // 到达边界点
          return 1;
      else if (a[m][n])   // 如果存在已经计算好的值,便直接取出
          return a[m][n];
      else {
      	// 无存在计算好的值,计算并存储放入数组
          a[m][n] =  uniquePaths(m-1, n) +  uniquePaths(n-1, m);
          return a[m][n];
      }
  }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值