查看: 1546| 回复: 8
跳转到指定楼层
上一主题 下一主题
收起左侧

[动态规划] 请教一道面试题

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
机器人从左上方到右下角
规则: 每步只能从 右上, 右边, 右下
基本的dp:dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1] + dp[i+1][j-1]
Follow up1: optimize space complexity
Follow up2: given 3 points in the matrix, check whether there is a path can go through these 3 points
Follow up3: given 3 points in the matrix, find out all the paths that can go through these 3 points.

请问有哪位大侠可以给一下3个follow up的code吗,学习一下,感激不尽。

上一篇:怎么才能更好的编程?(求大神指教)
下一篇:Moving zeros有思路可代码突然写不出来
🔗
 楼主| drift1981 2019-9-25 05:49:37 | 只看该作者
全局:
本帖最后由 drift1981 于 2019-9-25 05:50 编辑

follow up1, 我自己写了如下,但是有错误。大侠们能也帮忙看看吗
public static int findPaths2(int m, int n){
    int[] dp = new int[m];
    for(int i = 0; i < m; i++){
      dp[i] = 1;
    }
    for(int i = 1; i < n; i++){
      int[] tmp = new int[m];
      for(int j = 1; j < m; j++){
        tmp[j] = dp[j - 1] + dp[j];
        if(j != m - 1)
           tmp[j] += dp[j + 1];
      }
      dp = tmp;
    }
    return dp[m - 1];
}

评分

参与人数 1大米 +1 收起 理由
337845818 + 1 左上角出发是dp[0][[0] = 1, 看清楚题

查看全部评分

回复

使用道具 举报

🔗
psy 2019-9-25 06:23:46 | 只看该作者
全局:
本帖最后由 psy 于 2019-9-25 06:26 编辑
drift1981 发表于 2019-9-25 05:49
follow up1, 我自己写了如下,但是有错误。大侠们能也帮忙看看吗
public static int findPaths2(int m, i ...

这个解法在于你没有更新第一个row

public static int findPaths2(int m, int n){
    int[] dp = new int[m];
    for(int i = 0; i < m; i++){
      dp[i][i] = 1;
    }
    for(int i = 1; i < n; i++){
      int[] tmp = new int[m];
      for(int j = 0; j < m; j++){
// 不要遗漏了更新tmp[0]
        if (j != 0)
           tmp[j] += dp[j - 1];


        tmp[j] += dp[j];

        if(j != m - 1)
           tmp[j] += dp[j + 1];
      }
      dp = tmp;
    }
    return dp[m - 1];
}
[/i]
回复

使用道具 举报

🔗
 楼主| drift1981 2019-9-25 07:01:25 | 只看该作者
全局:
psy 发表于 2019-9-25 06:23
这个解法在于你没有更新第一个row

public static int findPaths2(int m, int n){

谢谢回复。

这个和我用如下,最basic的解法的返回答案是不同的,很困惑:

///////
  public static int findPaths1(int m, int n){
    // dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + dp[i + 1][j]
    int[][] dp = new int[m][n];
    for(int i = 0; i < m; i++){
      dp[i][0] = 1;
    }
    for(int j = 0; j < n; j++){
      dp[0][j] = 1;
    }
   
    for(int i = 1; i < m; i++){
      for(int j = 1; j < n; j++){
        dp[i][j] = dp[i - 1][j - 1] + dp[i][j - 1];
        if(i < m - 1){
          dp[i][j] += dp[i + 1][j - 1];
        }
      }
    }
    return dp[m - 1][n - 1];
  }
回复

使用道具 举报

🔗
337845818 2019-9-25 10:35:01 | 只看该作者
全局:
杨辉三角的基本用法吧。。

dp[i, j] = dp[i - 1, j - 1] + dp[i, j - 1] + dp[i + 1, j - 1]

i为上下, j为左右,越界标0即可。
省空间就是两个数组。

第二问 是否存在就看在不在+1, -1的斜率里面即可。

第三问 拆成3个从左往右的点,分别做一次。

回复

使用道具 举报

🔗
psy 2019-9-26 00:05:01 | 只看该作者
全局:
drift1981 发表于 2019-9-25 07:01
谢谢回复。

这个和我用如下,最basic的解法的返回答案是不同的,很困惑:

我assume你的basic解法里dp演变公式没有typo,
dp[i][j] = dp[i - 1][j - 1] + dp[j - 1];
就说解法思想,因为你的基本解法中也没有更新dp[0][i],你的解法里dp[0][i] 永远都是1,而根据题目描述,这一行是左下,左 的合

1 2 5 。。。
1 3 8 。。。
1 3 8 。。。
1 2 5 。。。
回复

使用道具 举报

🔗
 楼主| drift1981 2019-9-27 07:15:36 | 只看该作者
全局:
337845818 发表于 2019-9-25 10:35
杨辉三角的基本用法吧。。

dp = dp + dp + dp

请问大侠可以再指导一下吗。
我重新读题,照这种题意。dp[0][0] = 1。从左上角到右下角。 i, j 位置只能从前一列的上中下位置走到。那不是如果row == col, 就只有一条路,如果row > col, 就没有路, 如果row < col, 才有可能有大于一条路?
回复

使用道具 举报

🔗
337845818 2019-9-27 12:03:39 | 只看该作者
全局:
drift1981 发表于 2019-9-27 07:15
请问大侠可以再指导一下吗。
我重新读题,照这种题意。dp[0][0] = 1。从左上角到右下角。 i, j 位置只能 ...

是的你说的没错, 也就是我写的斜率+1, -1之间才有解。

本质上是个三分树 trinomial tree,不知道你熟悉不熟悉。

回复

使用道具 举报

🔗
是姐姐啊 2019-10-19 12:48:54 | 只看该作者
全局:
感觉用这两个function就应该可以帮助解决所有follow up了吧:
  1.     public static boolean reachable(Point src, Point dst) {
  2.         if (dst.x <= src.x) return false;
  3.         return Math.abs(dst.y - src.y) <= Math.abs(dst.x - src.x);
  4.     }
  5.    
  6.     public static int numPaths(int height, Point src, Point dst) {
  7.         if (dst.x <= src.x) return 0;
  8.         int[] currCol = new int[height];
  9.         for (int i = 0; i < height; i++) {
  10.             currCol = 0;
  11.         }
  12.         currCol[src.y] = 1;
  13.         for (int x = src.x + 1; x <= dst.x; x++) {
  14.             int[] newCol = new int[height];
  15.             for (int y = 0; y < height; y++) {
  16.                 int topLeft = (y > 0) ? currCol[y - 1] : 0;
  17.                 int left = currCol[y];
  18.                 int botLeft = (y < height - 1) ? currCol[y + 1] : 0;
  19.                 newCol[y] = topLeft + left + botLeft;
  20.             }
  21.             currCol = newCol;
  22.         }
  23.         return currCol[dst.y];
  24.     }
复制代码

评分

参与人数 3大米 +7 收起 理由
tryharder11 + 1
iPhD + 3 给你点个赞!
Vinay + 3 严禁人身攻击、脏话、戾气,屡犯会被封号!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表