前言
大家好,我是jiantaoyab,下面的题目用的方法和前面几篇的方法是一样的,写起来是比较困难的,加油
字母大小写全排列
https://leetcode.cn/problems/letter-case-permutation/
解析
代码
class Solution {vector<string> ret;string path;
public:char change(char ch){return (ch >= 'a' && ch <= 'z') ? ch -= 32 : ch += 32;}void dfs(string s, int pos){if(pos == s.size()){ret.push_back(path);return;}//不改变char ch = s[pos];path.push_back(ch);dfs(s, pos + 1);path.pop_back();//改变if(ch > '9' || ch < '0'){char tmp = change(ch);path.push_back(tmp);dfs(s, pos + 1);path.pop_back();}}vector<string> letterCasePermutation(string s) {dfs(s, 0);return ret;}
};
N 皇后
https://leetcode.cn/problems/n-queens/
解析
代码
class Solution {bool check_col[10]; //判断同一列有没有出现过bool dig1[20]; //判断主对角线有没有出现过bool dig2[20]; //判断副对角线有没有出现过vector<string> path;vector<vector<string>> ret;
public:void dfs(int n, int row){if(path.size() == row){ret.push_back(path);return;}for(int col = 0; col < n; col++) //尝试在这一行放皇后{if(!check_col[col] && !dig1[row - col + n] && !dig2[row + col]){path[row][col] = 'Q';check_col[col] = dig1[row - col + n] = dig2[row + col] = true;dfs(n, row + 1);path[row][col] = '.';check_col[col] = dig1[row - col + n] = dig2[row + col] = false;}}}vector<vector<string>> solveNQueens(int n) {path.resize(n);for(int i = 0; i < n; i++)path[i].append(n, '.'); //默认给n*n的棋盘都给上一个'.'dfs(n, 0);return ret;}
};
优美的排列
https://leetcode.cn/problems/beautiful-arrangement/
解析
若整数a除以非零整数b,商为整数,且没有余数, 我们就说a能被b整除(或说 b能整除a)
代码
这道题目也是用排列的方法去做的
class Solution {bool check[16];int ret;
public:void dfs(int pos, int n){if(pos == n + 1) {ret++;return;}for(int i = 1; i <= n; i ++) //数组{if(check[i] == false && (pos % i == 0 || i % pos == 0)){check[i] = true;dfs(pos + 1, n);check[i] = false;} }}int countArrangement(int n) {dfs(1, n);return ret;}
};
有效的数独
https://leetcode.cn/problems/valid-sudoku/
解析
代码
class Solution {bool check_row[9][10];bool check_col[9][10];bool check_gird[3][3][10];
public:bool isValidSudoku(vector<vector<char>>& board) {for(int i = 0; i < 9; i++){for(int j = 0; j < 9; j++){if(board[i][j] != '.'){int num = board[i][j] - '0';//判断数字是不是合法if(check_row[i][num] || check_col[j][num] || check_gird[i / 3][j / 3][num]) {return false;}check_row[i][num] = check_col[j][num] = check_gird[i / 3][j / 3][num] = true;}}}return true;}
};
解数独
https://leetcode.cn/problems/sudoku-solver/
解析
代码
class Solution {bool check_row[9][10];bool check_col[9][10];bool check_gird[3][3][10];
public:bool dfs(vector<vector<char>>& board){for(int i = 0; i < 9; i++){for(int j = 0; j < 9; j++){if(board[i][j] == '.'){//开始从 1 - 9 一个个试for(int num = 1; num <= 9; num++){if( !check_row[i][num] && !check_col[j][num] && !check_gird[i / 3][j / 3][num]){board[i][j] = num + '0';check_row[i][num] = check_col[j][num] = check_gird[i / 3][j / 3] [num] = true;if(dfs(board) == true) return true; //说明这一行填满了,能到下一行去填//恢复board[i][j] = '.';check_row[i][num] = check_col[j][num] = check_gird[i / 3][j / 3] [num] = false;}}//走到这里说明 1 - 9 都试过了都不行,那这种方法就不用了return false;}}}return true;}void solveSudoku(vector<vector<char>>& board) {//开始的时候先将已经有的数字搞成truefor(int i = 0; i < 9; i++){for(int j = 0; j < 9; j++){if(board[i][j] != '.'){int num = board[i][j] - '0';check_row[i][num] = check_col[j][num] = check_gird[i / 3][j / 3][num] = true;}}}//填数独dfs(board);}
};
单词搜索(向量偏移)
https://leetcode.cn/problems/word-search/
解析
代码
class Solution {bool check[7][7];int m, n;
public://偏移量数组int dx[4] = {0, 0, 1, -1};int dy[4] = {-1, 1, 0, 0};bool dfs(vector<vector<char>>& board,string& word, int i, int j, int pos){if(pos == word.size()) return true;for(int d = 0; d < 4; d++){int x = i + dx[d], y = j + dy[d];if( (x >= 0 && x < m) && (y >= 0 && y < n) && !check[x][y] && board[x][y] == word[pos] ){check[x][y] = true;if(dfs(board, word, x, y, pos + 1) == true) return true;check[x][y] = false;}}//前后左右都没有,返回faslereturn false;}bool exist(vector<vector<char>>& board, string word) {m = board.size();n = board[0].size();for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(board[i][j] == word[0]){check[i][j] = true;if(dfs(board, word, i, j, 1) == true) return true;check[i][j] = false;}}}return false;}
};
黄金矿工
https://leetcode.cn/problems/path-with-maximum-gold/
和上面的单词搜索的题目解法是一样的
代码
class Solution {bool check[16][16];int m, n;int ret = 0;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};
public:void dfs(vector<vector<int>>& grid, int i, int j, int path){ret = max(ret, path);for(int d = 0; d < 4; d++){int x = i + dx[d], y = j + dy[d];if((x >= 0 && x < m) && (y >= 0 && y < n) && !check[x][y] && grid[x][y]){check[x][y] = true;dfs(grid, x, y, grid[x][y] + path);check[x][y] = false;}}} int getMaximumGold(vector<vector<int>>& grid) {m = grid.size();n = grid[0].size();for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){if(grid[i][j]){check[i][j] = true;dfs(grid, i, j, grid[i][j]);check[i][j] = false;}}}return ret;}
};
不同路径 III
https://leetcode.cn/problems/unique-paths-iii/
解析
代码
class Solution {bool check[15][15];int n, m, ret = 0;int step = 0;int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};
public:void dfs(vector<vector<int>>& grid, int i, int j, int count){//到了终点if(grid[i][j] == 2){if(count == step) //路径合法{ret++;}return;}for(int d = 0; d < 4; d++){int x = i + dx[d], y = j + dy[d];if((x >= 0 && x < m) && (y >= 0 && y < n) && !check[x][y] && grid[x][y] != -1){check[x][y] = true;dfs(grid, x, y, count + 1);check[x][y] = false;}}}int uniquePathsIII(vector<vector<int>>& grid) {m = grid.size();n = grid[0].size();int begin_x,begin_y;for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){if(grid[i][j] == 0) step++;else if(grid[i][j] == 1){begin_x = i;begin_y = j;}}}step += 2; //把起点和终点也加上check[begin_x][begin_y] = true;dfs(grid, begin_x, begin_y, 1); //从这里开始计数为1return ret;}
};
括号生成
https://leetcode.cn/problems/IDBivT/
解析
有效挂号
- 左边挂号数目 = 右边挂号数目
- 递归到当前节点的时候,左边括号数 >= 右边括号数
代码
class Solution {vector<string> ret;string path;
public:void dfs(int left, int right, int n){if(right == n){ret.push_back(path);return;}//不满足这2个if的都被剪掉了if(left < n){//选(path += '(';left ++;dfs(left, right, n);path.pop_back();left--;}if(right < left){path += ')';right++ ;dfs(left, right, n);path.pop_back();right--;}}vector<string> generateParenthesis(int n) {dfs(0, 0, n);return ret;}
};
组合
https://leetcode.cn/problems/combinations/
解析
代码
class Solution {vector<int> path;vector<vector<int>> ret;
public://pos用来表示下一次就从下一个位置直接开始,达到去重的目的void dfs(int n, int k, int pos){if(path.size() == k){ret.push_back(path);return;}for(int i = pos; i <= n; i++){ path.push_back(i);dfs(n, k, i + 1);path.pop_back(); }}vector<vector<int>> combine(int n, int k) {dfs(n ,k, 1);return ret;}
};
目标和
https://leetcode.cn/problems/target-sum/
代码
这里sum用作为参数的方式去递归,sum + nums[pos] 等调用完回来的值还是sum原来的值
class Solution {int ret = 0;
public:void dfs(vector<int>& nums, int target, int pos, int sum){if(pos == nums.size()){if(sum == target){ret++; }return;}//选正dfs(nums, target, pos + 1, sum + nums[pos]);//选负dfs(nums, target, pos + 1, sum - nums[pos]);}int findTargetSumWays(vector<int>& nums, int target) {dfs(nums, target, 0, 0);return ret;}
};
组合总和
https://leetcode.cn/problems/combination-sum/
解析
代码
class Solution {vector<vector<int>> ret;vector<int> path;
public:void dfs(vector<int>& candidates, int target, int pos, int sum){if(sum == target){ret.push_back(path);return ;}if(sum > target || pos == candidates.size()) return;for(int i = pos; i < candidates.size(); i++){path.push_back(candidates[i]);dfs(candidates, target, i, sum + candidates[i]);path.pop_back();}}vector<vector<int>> combinationSum(vector<int>& candidates, int target) {dfs(candidates, target, 0, 0);return ret;}
};