【LeetCode】62. Unique Paths(C++)

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

题目:

A robot is located at the top-left corner of a m ∗ n m * n mn 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?
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

理解:

用dp做就可以了。当前位置的可能等于从左边过来和从上面过来两种,则到达当前位置可能数就是dp[i-1][j]和dp[i][j-1]之和。

实现:

自己的实现,比较笨

class Solution {
public:
	int uniquePaths(int m, int n) {
		if (m == 1 || n == 1) return 1;
		vector<vector<int>> dp(n, vector<int>(m,0));
		dp[0][1] = dp[1][0] = 1;
		for (int i = 0; i < n; ++i) {
			for (int j = 0; j < m; ++j) {
				int left = i >= 1 ? dp[i - 1][j] : 0;
				int top = j >= 1 ? dp[i][j - 1] : 0;
				dp[i][j] = left + top + dp[i][j];
			}
		}
		return dp[n - 1][m - 1];
	}
};

别人的实现

class Solution {
public:
	int uniquePaths(int m, int n) {
		vector<vector<int>> dp(n, vector<int>(m,1));
		for (int i = 1; i < n; ++i) {
			for (int j = 1; j < m; ++j) {
				dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
			}
		}
		return dp[n - 1][m - 1];
	}
};

但事实上,我们在每次循环中只用到了当前行和上一行,因此可以压缩空间复杂度。
if (m > n) return uniquePaths(n, m);是为了节约空间。

class Solution {
public:
	int uniquePaths(int m, int n) {
		if (m > n) return uniquePaths(n, m);
		vector<int> pre(m, 1), curr(m, 1);
		for (int i = 1; i < n; ++i) {
			for (int j = 1; j < m; ++j) {
				curr[j] = curr[j - 1] + pre[j];
			}
			swap(curr, pre);
		}
		return pre[m - 1];
	}
};

交换操作把curr换到了pre,而pre[0]永远都是0,后面的已经没有用了。
然而,交换操作也是多余的。因为curr是从左到右更新,因此还可以节约一个数组的空间。

class Solution {
public:
	int uniquePaths(int m, int n) {
		if (m > n) return uniquePaths(n, m);
		vector<int> dp(m, 1);
		for (int i = 1; i < n; ++i) {
			for (int j = 1; j < m; ++j) {
				dp[j] += dp[j - 1];
			}
		}
		return dp[m - 1];
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值