LeetCode——剑指 Offer 13 机器人的运动范围(JAVA)

该博客讨论了一道编程题,题目要求计算一个机器人在m行n列的方格中能到达多少个格子,条件是数位和不超过k。博主首先尝试了简单的方法,发现不适用,然后意识到需要使用深度优先搜索(DFS)来模拟机器人的移动,并考虑了边界条件、数位和限制以及已访问状态。博主在实现过程中遇到了Java中值传递和对象实例化的问题,并分享了解决方案。
摘要由CSDN通过智能技术生成

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

示例 1:

输入:m = 2, n = 3, k = 1
输出:3

示例 2:

输入:m = 3, n = 1, k = 0
输出:1

提示:

  • 1 <= n,m <= 100
  • 0 <= k <= 20

思路

刚开始做这题的时候,还以为只要计算二维数组中每个坐标点的数位和是否<=k即可,结果预期输出15,我输出了25。
后来一想,可能会出现一整行或者一整列的坐标点数位和都>k的情况,此时路径就被完全拦断,之后的点也到不了,所以,还是得用DFS来模拟机器人走路。

这题的大致想法就是让机器人从[0, 0]处开始,朝上下左右四个方向走,判断能否到达的条件就是:

  • 不越界;
  • 数位和小于等于k;
  • 未被访问过(这是为了防止走重复的路)。

总之,这题就是很简单的一道DFS。但是因为用JAVA写还是受了不少苦,主要是以下几个方面:

  • 关于JAVA中传值和传地址的问题:JAVA用基本数据类型都是传值,因此,如果想在dfs函数里传入可行点数cnt,则需要将cnt封装在一个类里面,然后把这个类传入函数才行;
  • 关于LeetCode在线输出和本地输出不一致的问题:LeetCode应该是实例化一个对象,然后多次调用我们写的这个功能函数去评测(来自:Bollie的回答),所以,写的时候,成员类名、方法名、变量名尽量都不要加上static,否则的话,就会导致对象多次调用的时候,使用的都是同一个变量/方法。

代码

public class Solution {
	class Count{//java传地址只能用类传,不像C++可以加别名&
		int num;
	}
	int[] dx = {0, 0, -1, 1};
	int[] dy = {-1, 1, 0, 0};
	boolean[][] visited = new boolean[110][110];
	public boolean digitalSum(int x, int y, int k) {//计算当前坐标的数位和
		int sum = 0;
		String xx = String.valueOf(x);
		String yy = String.valueOf(y);
		for(int i=0;i<xx.length();i++) {
			sum += xx.charAt(i)-48;//ASCII码-48
		}
		for(int i=0;i<yy.length();i++) {
			sum += yy.charAt(i)-48;
		}
		if(sum<=k) return true;
		else return false;
	}
	public boolean canReach(int x, int y, int m, int n, int k){//判断下一个点可不可达
		if(x<0||x>m-1||y<0||y>n-1) {//越界
			return false;
		}
		if(digitalSum(x, y, k)==false) {//数位和大于k
			return false;
		}
		if(visited[x][y]==true) {//已被访问过
			return false;
		}
		return true;
	}
	public void dfs(int x, int y, int m, int n, int k, Count cnt) {
		cnt.num++;
		visited[x][y] = true;
		for(int i=0;i<4;i++) {
			int next_x = x + dx[i];
			int next_y = y + dy[i];
			if(canReach(next_x, next_y, m, n, k)==true) {
				dfs(next_x, next_y, m, n, k, cnt);
			}
		}
	}
	public int movingCount(int m, int n, int k) {
		Count cnt = new Count();
		dfs(0, 0, m, n, k, cnt);
		return cnt.num;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值