前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构与算法第一期:机器人的运动范围

数据结构与算法第一期:机器人的运动范围

作者头像
程序员小王
发布2021-04-12 16:45:36
3440
发布2021-04-12 16:45:36
举报
文章被收录于专栏:架构说架构说

解题思路

image.png

代码语言:javascript
复制
机器人的运动范围:
地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。---数据结构就是矩阵
一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外), ---约束条件1 :顺时针
也不能进入行坐标和列坐标的数位之和大于k的格子。 -----约束条件2:
例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。
但它不能进入方格 [35, 38],因为3+5+3+8=19。
请问该机器人能够到达多少个格子? -------结束条件怎么判断

思维陷阱:

小白:

  • 需求描述:一个机器人从坐标 [0, 0] 的格子开始移动,请问该机器人能够到达多少个格子
  • 疑惑:这里没有告诉结束位置,我还能遍历吗?结束条件是什么
  • 程序语言:dfs遍历结束。访问能访问的路径。因此需要一个visited标记,走过路径不需要 (螺旋矩阵)需要回溯,换个方向(邻居/子节点) 这里根本矩阵结构,完全是输入坐标,只跟坐标有关系。不需要获取矩阵元素值。

初级:

  • 需求描述:一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上 下
  • 疑惑: 螺旋矩阵虽然是一个点是2个方向,为什么全部遍历,但是整体整体?迷路的机器人 机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)从一个位置到一个位置,不能遍历全部呀、 迷路的机器人告诉你重点位置,遍历提前结束。这是理想情况,假如你不退出就要全部遍历
  • 程序语言:1 dfs 每次都都2个,4个选择,最终全部遍历整个元素。升级tree遍历 每个元素和其他节点关系是2个关系,整个节点组合起来,是可以完成遍历的。2 螺旋矩阵 每个点移动方向 不一样,在非递归遍历 需要全局遍历dirction来标记, 在dfs中缺没有使用。随便尝试的
  1. a -b 有方向的,隐藏了一个概念, a 遍历过不需要访问。螺旋矩阵在此访问情况下,必须有额外空间标记。

中级:

  • 需求描述:非递归怎么实现
  • 程序语言:不在递归函数里,判断,而是开始时候,就要判断。

//https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/mian-shi-ti-13-ji-qi-ren-de-yun-dong-fan-wei-dfs-b/ //https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/jian-zhi-offerer-shua-javadfs-bfs-tu-jie-py05/

代码

代码语言:javascript
复制

var (
 visited [][]bool //元素第二次遍历需要回溯,防止重复遍历。很容易忘记
 rows    int
 cols    int
 sum     int
)

func movingCount(m int, n int, k int) int {
 //01 定义数据结构
 rows = m
 cols = n
 sum = k

 //go二维切片就是 int** 指针 vector<vector<bool>> 和java对象寓意是一样的。

 visited = make([][]bool, rows)

 for i := 0; i < rows; i++ {
  visited[i] =  make([]bool,cols)
 }

 //02 dfs遍历:不重复 不遗留
 
 return dfs(0,0);

}

func dfs(x int,y int) int {

 //约束条件1:
 if x <0 || x >=rows || y <0 || y >=cols {
  return 0//长度是0 相当于回溯返回了。进来--有走了
 }
    //约束条件2:
 if visited[x][y] == true {
  return 0 //重复元素不计算2次
 }
 //约束条件3:
 if get(x)+get(y) >sum {
  return 0
 }
 
 visited[x][y]  =true;

 return 1+dfs(x, y+1) + dfs(x+1, y)
}


 // 计算一个数的各个位数之和
 func  get(x int)  int{
  res := 0
 for x != 0 {
  res += x % 10
  x /= 10
 }
 return res
}

C++

  • 部分错误
代码语言:javascript
复制
struct Points
{
  int x;
  int y;
  Points(int a,int b)
  {
 x =a;
 y =b; 
  }
};

class Solution 
{
 public:
  //广度优先搜索:利用队列实现
  //只要边和边关系,2个方向是可以遍历全部节点的。
  //A gossip protocol is a procedure or process of computer peer-to-peer communication that is based on the way epidemics spread
  int movingCount(int m, int n, int k) {

   //O1 定义数据结构
   queue<Points> bfsQueue;
   vector<vector<bool> > visited(m,vector<bool>(n,false)); // ??????
   // 向右和向下的方向数组
   int postion[2][2] ={{0,1},{1,0}};
   
   //02 初始化数据
   bfsQueue.push(Points(0,0)); 
   //void push (value_type&& val);
   visited[0][0] =true; //很容易忘记

   //03 遍历结束条件
         int total =0;
   while(!bfsQueue.empty())
   {
    
   //约束条件:
   //放入到队列数据都是,没有被重复遍历过数据。
   //可以拿出来直接使用,因此不㤇判断是否重复
   Points  cur = bfsQueue.front();
   bfsQueue.pop();  
  
   //遍历迭代过程
  
   for(int i=0;i<2;i++)
   {
    int nextX =cur.x +postion[i][0];
    int nextY =cur.y +postion[i][1];

    //约束条件:通过移动位置寻找邻居,这个是计算出来的。
    // 因为没有创建邻居表这样图结构。
    if (nextX < 0 || nextX >= m 
     || nextY < 0 || nextY >= n 
     || visited[nextX][nextY] ==true
     || get(nextX) + get(nextY) > k) 
    {
     continue;
    }    
    bfsQueue.push(Points(nextX,nextY)); 
    total++; //遍历过程中,统计个数
    visited[nextX][nextY] =true;//遗留了

   }
   }
   return total;

  }

  int get(int x) {
   int res=0;
   for (; x; x /= 10){
    res += x % 10;
   }
   return res;
  }
};
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-04-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Offer多多 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解题思路
  • 思维陷阱:
  • 小白:
  • 初级:
  • 中级:
    • 代码
      • C++
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档