第十二周LeetCode算法题三道

第一道

题目名称:62. Unique Paths

题目难度:Medium

题目描述: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 3 x 7 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

题目分析:
题目的意思就是叫我们找出从一个矩阵的左上角走到右下角的所有不同的路径,有一个限制,就是每一步只能向右走或者是向下走。

这是一道基础的动态规划的题目。注意到每一个当前格子可能由两个不同的方向获得,要么就是从上面往下走,要么就是从左边往右走。所以当前格子所在的所有路径是它的上格子和左格子所在的所有路径之和。

所以思路就非常明显了。
下面是具体的AC代码:

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

第二道

题目名称:63. Unique Paths II

题目难度:Medium

题目描述:Follow up for “Unique Paths”:

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

The total number of unique paths is 2.

Note: m and n will be at most 100.

题目分析:
这道题是上一题的后续,基本条件一样,只是这次地图上多了些石头作为障碍,任何路径不能经过障碍。
思路也很简单,只需要在原来的基础上,检测到当前的格子是有石头的,那么说明“此路不通“,石头所在的格子不在任何路径上,路径数为0。

最后AC的代码为:

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        if (obstacleGrid.size() == 0) return 0;
        int m = obstacleGrid.size(), n = obstacleGrid[0].size();
        vector<vector<int>> path(m, vector<int>(n, 1));
        for (int i = 0; i < m; ++i) {
            if (obstacleGrid[i][0] == 1) {
                for (int j = i; j < m; ++j) {
                    path[j][0] = 0;
                }
                break;
            }
        }
        for (int i = 0; i < n; ++i) {
            if (obstacleGrid[0][i] == 1) {
                for (int j = i; j < n; ++j) {
                    path[0][j] = 0;
                }
                break;
            }
        }            
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (obstacleGrid[i][j] == 1) {
                    path[i][j] = 0;
                } else {
                    path[i][j] = path[i - 1][j] + path[i][j - 1];
                }
            }
        }
        return path[m - 1][n - 1];
    }
};

第三道

题目名称:62. Unique Paths

题目难度:Medium

题目描述:Given two integers n and k, return all possible combinations of k numbers out of 1 … n.

For example,
If n = 4 and k = 2, a solution is:

[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

题目分析:
题目的意思是要我们找出从1到n这n个数的所有组合,每个组合由k个数字组成。
可以采用枚举的方法,先枚举出1开头的所有组合,再枚举出2开头的所有组合,以此类推……

举个例子,n = 4 和 k = 2,那么一开始就是先枚举出1开头的所有组合:

[1,2] [1,3] [1,4]

再枚举出2、3开头的所有组合:

[2,3] [2,4]
[3,4]

如此便可遍历出所有情况。具体的,我们利用递归去遍历。将待使用的n个数看成由1,2,……,n组成的一个数组,利用一个num记录当前已经使用到了第num-1个数,接下来的步骤就从num这个数开始。每一次递归,将从num这个数开始的之后的数之中选择一个数,加入当前待补充的组合,然后再从这个数之后的数中开始新一轮的递归。递归结束的条件是,当前待补充的组合的长度等于k,或者是,当前待补充的组合的长度还没等于k,但是未使用的数已经不够填满这个空隙了。

具体的代码如下:

class Solution {
public:
    void findAll(vector<vector<int>> & result, vector<int> & current, int num, int & n, int & k) {
        if (current.size() == k) {
            result.push_back(current);
            return;
        } else if (num > n) {
            return;
        }
        for (int i = num; i <= n; ++i) {
            vector<int> temp(current);
            temp.push_back(i);
            findAll(result, temp, i + 1, n, k);
        }
    }
    vector<vector<int>> combine(int n, int k) {
        vector<vector<int>> result;
        vector<int> current;
        findAll(result, current, 1, n, k);
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值