《剑指Offer——12.矩阵中的路径,13.机器人的运动范围》代码
Posted 穿迷彩服的鲨鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer——12.矩阵中的路径,13.机器人的运动范围》代码相关的知识,希望对你有一定的参考价值。
12.矩阵中的路径,13.机器人的运动范围
前言
//==================================================================
// 《剑指Offer——12.矩阵中的路径,13.机器人的运动范围》代码
// 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有
// 字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、
// 上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入
// 该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字
// 母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个
// 字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// A B T G
// C F C S
// J D E H
// =================================================================
// 题目:地上有一个m行n列的方格。一个机器人从坐标(0, 0)的格子开始移动,它
// 每一次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和
// 大于k的格子。例如,当k为18时,机器人能够进入方格(35, 37),因为3+5+3+7=18。
// 但它不能进入方格(35, 38),因为3+5+3+8=19。请问该机器人能够到达多少个格子?
//==================================================================
一、示例
1.矩阵中的路径
/*********************************************************************
/*
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”
单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false
*/
***********************************************************************/
2.机器人的运动范围
/*********************************************************************
/*
地上有一个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
4 3 4
[(0,0)(0,1)(0,2)]
[(1,0)(1,1)(1,2)]
[(2,0)(2,1)(2,2)]
[(3,0)(3,1)(3,2)]
示例 2:
输入:m = 3, n = 1, k = 0
输出:1
*/
***********************************************************************/
二、代码解析
1.新建.cpp文件
代码如下(示例):
//==================================================================
// 《剑指Offer——12.矩阵中的路径,13.机器人的运动范围》代码
// 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有
// 字符的路径。路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左、右、
// 上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入
// 该格子。例如在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字
// 母用下划线标出)。但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个
// 字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
// A B T G
// C F C S
// J D E H
// =================================================================
// 题目:地上有一个m行n列的方格。一个机器人从坐标(0, 0)的格子开始移动,它
// 每一次可以向左、右、上、下移动一格,但不能进入行坐标和列坐标的数位之和
// 大于k的格子。例如,当k为18时,机器人能够进入方格(35, 37),因为3+5+3+7=18。
// 但它不能进入方格(35, 38),因为3+5+3+8=19。请问该机器人能够到达多少个格子?
//==================================================================
#include <iostream>
#include<vector>
using namespace std;
/*
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”
单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false
*/
/*回溯*/
bool hasPath(vector<vector<char>>& board, int row, int col, int rows, int cols, string word, int k)
{
if (row < 0 || row >= rows || col < 0 || col >= cols || board[row][col] != word[k])
{
return false;
}
if (k == word.size() - 1)
{
return true;
}
board[row][col] = '\\0';
bool res = hasPath(board, row + 1, col, rows, cols, word, k + 1) ||
hasPath(board, row, col + 1, rows, cols, word, k + 1) ||
hasPath(board, row - 1, col, rows, cols, word, k + 1) ||
hasPath(board, row, col - 1, rows, cols, word, k + 1);
board[row][col] = word[k];
return res;
}
bool exist(vector<vector<char>>& board, string word)
{
if (board.empty() || word.empty())
{
return false;
}
int rows = board.size();
int cols = board[0].size();
int k = 0;
for (int row = 0; row < rows; ++row)
{
for (int col = 0; col < cols; ++col)
{
if (hasPath(board, row, col, rows, cols, word, k))
{
return true;
}
}
}
return false;
}
/*
地上有一个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
4 3 4
[(0,0)(0,1)(0,2)]
[(1,0)(1,1)(1,2)]
[(2,0)(2,1)(2,2)]
[(3,0)(3,1)(3,2)]
示例 2:
输入:m = 3, n = 1, k = 0
输出:1
*/
/*法一----回溯*/
int getDigitSum(int number)
{
int sum = 0;
while (number > 0)
{
sum += number % 10;
number /= 10;
}
return sum;
}
bool check(int k, int rows, int cols, int row, int col, vector<vector<bool>>& visited)
{
if (row >= 0 && row < rows && col >= 0 && col < cols
&& getDigitSum(row) + getDigitSum(col) <= k && !visited[row][col])
{
return true;
}
return false;
}
int movingCountCore(int k, int rows, int cols, int row, int col, vector<vector<bool>>& visited)
{
int count = 0;
if (check(k, rows, cols, row, col, visited))
{
visited[row][col] = true;
count = 1 + movingCountCore(k, rows, cols, row - 1, col, visited) +
movingCountCore(k, rows, cols, row + 1, col, visited) +
movingCountCore(k, rows, cols, row, col - 1, visited) +
movingCountCore(k, rows, cols, row, col + 1, visited);
}
return count;
}
int movingCount1(int m, int n, int k)
{
if (m <= 0 || n <= 0 || k < 0)
{
return 0;
}
vector<vector<bool>> visited(m, vector<bool>(n, false));
int count = movingCountCore(k, m, n, 0, 0, visited);
return count;
}
/*法二----递推*/
int movingCount2(int m, int n, int k)
{
if (!k)return 1;
if (m <= 0 || n <= 0 || k < 0)return 0;
vector<vector<int>> visited(m, vector<int>(n, 0));
int res = 0;
visited[0][0] = 1;
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
{
if (getDigitSum(i) + getDigitSum(j) > k)continue;
if (i - 1 >= 0)
{
visited[i][j] |= visited[i - 1][j];
}
if (j - 1 >= 0)
{
visited[i][j] |= visited[i][j - 1];
}
res += visited[i][j];
}
}
return res;
}
int main()
{
vector<vector<char>> board =
{
{ 'A', 'B','C', 'E'},
{ 'S', 'F', 'C', 'S'},
{ 'A', 'D', 'E', 'E'}
};
string word = "ABCCED";
cout << "《剑指Offer——12.矩阵中的路径》代码" << endl;
cout << exist(board, word) << endl << endl;
cout << "剑指 Offer 13. 机器人的运动范围" << endl;
cout << "法一----回溯" << movingCount1(16, 8, 4) << endl;
cout << "法二----递推" << movingCount2(16, 8, 4) << endl;
return 0;
}
三,测试
以上是关于《剑指Offer——12.矩阵中的路径,13.机器人的运动范围》代码的主要内容,如果未能解决你的问题,请参考以下文章
剑指 Offer(C++版本)系列:剑指 Offer 12 矩阵中的路径
剑指 Offer(C++版本)系列:剑指 Offer 12 矩阵中的路径