回溯法模板(矩阵中操作)
在矩陣中考察回溯算法,分為任意起點、左上角開始等情況。從而有不同的模板,其實區別就是直接開始還是每個坐標都去嘗試。
目錄
1.首先是從左上角開始這種情況
C++代碼
2.從矩陣任意一點開始的情況
C++代碼:
1.首先是從左上角開始這種情況
劍指 Offer 13. 機器人的運動范圍
難度中等291收藏分享切換為英文接收動態反饋
地上有一個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示例 2:
輸入:m = 3, n = 1, k = 0 輸出:1提示:
- 1 <= n,m <= 100
- 0 <= k?<= 20
C++代碼:
class Solution {vector<vector<int>> visit; public:int sum(int x,int y){int res=0;while(x){res+=x%10;x/=10;}while(y){res+=y%10;y/=10;}return res;}int dfs(int x, int y, int m, int n, int k){if(x < 0 || x >= m || y < 0 || y >= n || visit[x][y] || sum(x, y)>k) return 0;visit[x][y] = 1;return dfs(x-1,y,m,n,k)+dfs(x,y-1,m,n,k)+dfs(x+1,y,m,n,k)+dfs(x,y+1,m,n,k)+1;}int movingCount(int m, int n, int k) {if(k == 0) return 1;//k等于0應該輸出1visit.resize(m, vector<int>(n, 0));return dfs(0, 0, m, n, k);} };?
2.從矩陣任意一點開始的情況
劍指 Offer 12. 矩陣中的路徑
難度中等323收藏分享切換為英文接收動態反饋
給定一個?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提示:
- 1 <= board.length <= 200
- 1 <= board[i].length <= 200
- board?和?word?僅由大小寫英文字母組成
C++代碼:
class Solution {vector<vector<int>> visit;const int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};//定義上下左右四個方向public:bool check(vector<vector<char>>& board, string word, int i, int j, int k){if(i >= board.size() || i < 0 || j >= board[0].size() || j < 0 || visit[i][j] || board[i][j] != word[k])return false;if(k == word.size() - 1) return true;char tmp = board[i][j];visit[i][j] = 1;for(int d = 0; d < 4; d++){if(check(board, word, i + dx[d], j + dy[d], k+1)) return true;}visit[i][j] = 0;return false;}bool exist(vector<vector<char>>& board, string word) {int row = board.size(), col = board[0].size(), len = word.size();visit.resize(row, vector<int>(col, 0));if(len > row*col || word.empty()) return false;for(int i = 0; i < row; i++){for(int j = 0; j < col; j++){if(check(board, word, i, j, 0))return true;}}return false;} };可以直接改變字符數組,節約訪問記錄數組空間。
class Solution {vector<vector<int>> visit;const int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};//定義上下左右四個方向public:bool check(vector<vector<char>>& board, string word, int i, int j, int k){if(i >= board.size() || i < 0 || j >= board[0].size() || j < 0 || visit[i][j] || board[i][j] != word[k])return false;if(k == word.size() - 1) return true;char tmp = board[i][j];board[i][j] = '/'; //占位符 訪問過的就不再管//visit[i][j] = 1;for(int d = 0; d < 4; d++){if(check(board, word, i + dx[d], j + dy[d], k+1)) return true;}board[i][j] = tmp; //回溯的時候需要復原//visit[i][j] = 0;return false;}bool exist(vector<vector<char>>& board, string word) {int row = board.size(), col = board[0].size(), len = word.size();visit.resize(row, vector<int>(col, 0));if(len > row*col || word.empty()) return false;for(int i = 0; i < row; i++){for(int j = 0; j < col; j++){if(check(board, word, i, j, 0))return true;}}return false;} };總結
以上是生活随笔為你收集整理的回溯法模板(矩阵中操作)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言 swap交换函数_重审C中老生常
- 下一篇: C++ 数值的整数次方 (最小int取反