矩陣中上下左走四個方向移動
矩陣用一維數組表示,行數rows,列數cols
與矩陣有關,考慮定義行號i,列號j,
index=i*cols+j
牛客網劍指offer 65 矩陣中的路徑
思路:遞歸
1,矩陣中元素是否已經訪問——一個格子只能走一次
定義與矩陣大小相同的一維數組做標記數組flag`
//標誌位,初始化爲false
boolean[] flag = new boolean[matrix.length];
2,遞歸終止條件
條件一,越界?,相等?,元素是否已經訪問過?
(i<0 || j<0 || i>=rows || j>=cols || matrix[index] != str[k] || flag[index] == true)
條件二:待查字符串已遍歷完
(k == str.length-1)
3,返回
true/false
不能直接返回遞歸函數,因爲還有其他路徑可以試,標誌位要還原
這一條路不通,還原,再試其他的路徑
4,代碼
public class Solution {
public boolean hasPath(char[] matrix, int rows, int cols, char[] str)
{
//標誌位,初始化爲false
boolean[] flag = new boolean[matrix.length];
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
//循環遍歷二維數組,找到起點等於str第一個元素的值,再遞歸判斷四周是否有符合條件的----回溯法
if(judge(matrix,i,j,rows,cols,flag,str,0)){
return true;
}
}
}
return false;
}
//judge(初始矩陣,索引行座標i,索引縱座標j,矩陣行數,矩陣列數,待判斷的字符串,字符串索引初始爲0即先判斷字符串的第一位)
private boolean judge(char[] matrix,int i,int j,int rows,int cols,boolean[] flag,char[] str,int k){
//先根據i和j計算匹配的第一個元素轉爲一維數組的位置
int index = i*cols+j;
//遞歸終止條件
if(i<0 || j<0 || i>=rows || j>=cols || matrix[index] != str[k] || flag[index] == true)
return false;
//若k已經到達str末尾了,說明之前的都已經匹配成功了,直接返回true即可
if(k == str.length-1)
return true;
//要走的第一個位置置爲true,表示已經走過了
flag[index] = true;
//回溯,遞歸尋找,每次找到了就給k加一,找不到,還原
if(judge(matrix,i-1,j,rows,cols,flag,str,k+1) ||
judge(matrix,i+1,j,rows,cols,flag,str,k+1) ||
judge(matrix,i,j-1,rows,cols,flag,str,k+1) ||
judge(matrix,i,j+1,rows,cols,flag,str,k+1) )
{
return true;
}
//走到這,說明這一條路不通,逆遞歸還原,再試其他的路徑
flag[index] = false;
return false;
}
}
牛客網劍指offer 66 機器人的運動範圍
思路:遞歸
1,矩陣中元素是否已經訪問——一個格子只能走一次
定義與矩陣大小相同的一維數組做標記數組flag`
//標誌位,初始化爲false
boolean[] flag = new boolean[matrix.length];
2,遞歸終止條件
(i<0 || j<0 || i>=rows || j>=cols || matrix[index] != str[k] || flag[index] == true)
3,返回
1+遞歸函數返回值
4,代碼
public class Solution {
public int movingCount(int threshold, int rows, int cols)
{
int len = rows*cols;
boolean[] flag = new boolean[len]; //記錄是否已經走過
return helper(0, 0, rows, cols, flag, threshold);
}
private int helper(int i, int j, int rows, int cols, boolean[] flag, int threshold) {
int index=i*cols+j;
//遞歸終止條件
if (i < 0 || i >= rows || j < 0 || j >= cols || numSum(i) + numSum(j) > threshold || flag[index] == true)
return 0;
flag[index] = true;
return 1+ helper(i - 1, j, rows, cols, flag, threshold)
+ helper(i + 1, j, rows, cols, flag, threshold)
+ helper(i, j - 1, rows, cols, flag, threshold)
+ helper(i, j + 1, rows, cols, flag, threshold);
}
private int numSum(int i) {
int sum = 0;
do{
sum += i%10;
}while((i = i/10) > 0);
return sum;
}
}