剑指 Offer 13. 机器人的运动范围 广度优先遍历

剑指 Offer 13. 机器人的运动范围

题目:地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

题目链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/

方法一:图的广度优先遍历:

思路:
由题干可知机器人只能够上下左右移动,这说明可能有些区域能够满足小于k但是机器人本身无法到达该区域。(大部分的可行区间集中于数组的左半边),所以通过数组遍历的方法不能够有效的判断哪些区域是机器人不可达的,所以考虑使用广度优先遍历算法进行求解。

实现代码如下:

    public static int movingCount(int m, int n, int k) {
    	int[] dx= {0,0,1,-1};
    	int[] dy= {1,-1,0,0};
    	int res=0;
    	Queue<int[]> que =new ArrayDeque<>();
    	int[][] area=new int[m][n];
    	area[0][0]=0;
    	que.offer(new int[] {0,0});
    	int[] point=null;
    	while(!que.isEmpty()) {
    		point=que.poll();
    		int x=point[0],y=point[1];
    		if(count(x,y,k)) {
    			if((x<m&&y<n) &&area[x][y]!=1) {
    				res++;
    				area[x][y]=1;
    				}
    		}
    		for(int i=0;i<4;i++) {
    			int newX=x+dx[i];
    			int newY=y+dy[i];
    			if(newX<0||newY<0||newX>m||newY>n||area[newX][newY]==1)continue;
    			if(count(newX,newY,k)) {
    				area[newX][newY]=1;
    				res++;
    				que.offer(new int[] {newX,newY});
    			}
    		}
    		
    	}
    	return res;
    }
    public static boolean count(int num,int mun,int k) {
    	int res=0;
    	while(num/10!=0) {
    		res+=num%10;
    		num/=10;
    	}
    	while(mun/10!=0) {
    		res+=mun%10;
    		mun/=10;
    	}
    	res+=num;
    	res+=mun;
    	if(res>k)return false;
    	return true;
    }

图的广度优先遍历模板:

我理解的广度优先遍历算法大概分为:方向数组、双端链表(ArrayDeque)、循环体(完成图的功能要求)、图的更新(处理过的值进行标记)四个部分。

方向数组:

根据题目要求来设计方向数组。

//上下左右:
    	int[] dx= {0,0,1,-1};
    	int[] dy= {1,-1,0,0};
//四周
    	int[] dx= {-1,-1,-1,0,0,1,1,1};
    	int[] dy= {-1,0,1,-1,1,-1,0,1};

具体情况根据实际情况考虑。可能也会有各种各样的情况(三维、定向)。

双端链表

采用双端链表来进行循环。
采用双端链表的目的:其实本质上是需要的是一个前出后进的队列。

//定义
Queue<int[]> que =new ArrayDeque<>();
//存入
que.offer(new int[]{0,0});
//取出
int[] point=que.poll();
//判断为空
que.isEmpty();

循环体和更新数组

具体情况具体分析单独讲没什么参考性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值