# leetcode算法题-剑指Offer篇（4）

### 1、 矩阵中的路径

#### 1.1 题目描述：

[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]

#### 1.2 题解

##### 1.2.1 深度优先搜索 DFS

public boolean exist(char[][] board, String word) {
char[] words = word.toCharArray();

for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, words, i, j, 0)) return true;
}
}
return false;
}

/**
* @param board 矩阵
* @param word  目标字符串
* @param i     矩阵行
* @param j     矩阵列
* @param k
* @return
*/
public boolean dfs(char[][] board, char[] word, int i, int j, int k) {
if (i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[k]) return false;
if (k == word.length - 1) return true;
char temp = board[i][j];
board[i][j] = '/';//标记已读
boolean result =  dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) ||
dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
board[i][j] = temp;//将标记取消
return result;
}


### 2、机器人的运动范围

#### 2.2 题解

##### 2.2.1 深度优先

public int movingCount(int m, int n, int k) {
if (m <= 0 || n <= 0 || k < 0)
return 0;
int[] visit = new int[m * n];
return help(0, 0, k, m, n, visit);

}
/**
* @param row   行
* @param col   列
* @param k
* @param m
* @param n
* @param visit 是否已经计算过
* @return
*/
public int help(int row, int col, int k, int m, int n, int[] visit) {
if (row < 0 || col < 0 || row >= m || col >= n || visit[row*n+col] == 1 || sum(row, col) > k)
return 0;
visit[row * n + col] = 1;
return 1 + help(row + 1, col, k, m, n, visit)
+ help(row - 1, col, k, m, n, visit)
+ help(row, col + 1, k, m, n, visit)
+ help(row, col - 1, k, m, n, visit);
}
/**
* 计算和
* @param m
* @param n
* @return
*/
public int sum(int m, int n) {
int sum = 0;
while (m != 0) {
sum += m % 10;
m /= 10;
}
while (n != 0) {
sum += n % 10;
n /= 10;
}
return sum;
}

##### 2.2.2 广度优先
public int movingCount(int m, int n, int k) {
boolean[] visited = new boolean[m * n];
int res=0;
while(queue.size()>0){
int[] x=queue.poll();
int row = x[0], col =x[1],sum=sum(row)+sum(col);
if(row>=m||col>=n||sum>k||visited[row*n+col]==true)continue;
visited[row*n+col]=true;
res++;
}
return res;
}

/**
* 计算和
*
* @param m
* @return
*/
public int sum(int m) {
int sum = 0;
while (m != 0) {
sum += m % 10;
m /= 10;
}
return sum;
}


### 3、剪绳子

#### 3.2 题解

##### 3.2.1 找规律

3：2x1=2；4：2x2=4；
5：3x2=6；6：3x3=9;
7：3x2x2=12；8:：3x3x2=18
9：3x3x3=27；10：3x3x2x2=36;


public int cuttingRope(int n) {
if(n <= 3) return n - 1;
else {
int k = (n % 3 == 0 ? (n / 3) : ((n - 2) / 3));//k为3的个数
int j = (n + 2) / 3-k;//j为2的个数
int mul = 1;
while (k >0) {
mul*=3;
k--;
}
while(j>0){
mul*=2;
j--;
}
return mul;
}
}

##### 3.2.2 贪心算法
 public int cuttingRope(int n) {
if(n <= 3) return n - 1;
long res=1L;
//贪心算法，优先切三，其次切二
while(n>4){
res=res*3;
n-=3;
}
//出来循环只有三种情况，分别是n=2、3、4
return res*n;
}


04-23 661
01-24 233
05-08 1012
08-26
10-27 600