劍指Offer-機器人的運動範圍
地上有一個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。請問該機器人能夠到達多少個格子?
示例 1:
輸入:m = 2, n = 3, k = 1
輸出:3
示例 1:
輸入:m = 3, n = 1, k = 0
輸出:1
思路
與《矩陣中的路徑》那道題類似,也是dfs+回溯,不過這道題有一些可以優化的點。
首先,通過分析解的情況,我們可以知道機器人只能向右或者向下走(類似一個直角三角形),排除向左和向上走的情況。
利用一個記憶矩陣visited,標識已經走過的路。不能重複地走。也是爲了遞歸函數的出棧。
class Solution {
//記憶矩陣
boolean[][] visited;
public int movingCount(int m, int n, int k) {
//對記憶矩陣初始化
this.visited=new boolean[m][n];
return dfs(m,n,0,0,k);
}
public int dfs(int m,int n,int i,int j,int k)
{
if(i<0 || i>=m || j<0 || j>=n || getSum(i,j)>k || visited[i][j])
{
return 0;
}
//設置標記,回溯回來的時候直接返回
visited[i][j]=true;
//這裏直接返回,與《矩陣中路徑》那題不同,因爲那題是窮舉所有可能性,這題是找最大值,且不會
//遍歷矩陣中所有元素,只是從(0,0)點出發深搜回溯而已。
//根據直角三角形的形狀,只向右或向下走。
return 1+(dfs(m,n,i+1,j,k) + dfs(m,n,i,j+1,k));
}
//獲得某個點橫縱座標的位數和的函數
public int getSum(int x,int y)
{
int sum=0;
while(x>0)
{
sum+=x%10;
x=x/10;
}
while(y>0)
{
sum+=y%10;
y=y/10;
}
return sum;
}
}