题目链接：N 皇后按照国际象棋的规则，皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上，并且使皇后彼此之间不能相互攻击。给你一个整数 n ，返回所有不同的 n 皇后问题 的解决方案。每一种解法包含一个不同的 n 皇后问题 的棋子放置方案，该方案中 'Q' 和 '.' 分别代表了皇后和空位。方法一：回溯class Solution { public: vector<vector<string>> ans; int m[15][15]; bool check(int x,int y,int n) { for (int i = 0;i < x;i++) { if (m[i][y]) return false; } for (int i = 0;i < y;i++) { if (m[x][i]) return false; } int num = min(x,y); // 左上 for (int i = 1;i <= num;i++) { if (m[x-i][y-i]) return false; } num = min(x,n-y); //右上 for (int i = 1;i <= num;i++) { if (m[x-i][y+i]) return false; } num = min(n-x,n-y); return true; } void f(int n,int x) { if (x >= n) { vector<string> t; for (int i = 0;i < n;i++) { string s = ""; for (int j = 0;j < n;j++) { if (m[i][j] == 1) { s += "Q"; }else { s += "."; } } t.push_back(s); } ans.push_back(t); return ; } for (int i = 0;i < n;i++) { if (check(x,i,n)) { m[x][i] = 1; f(n,x+1); m[x][i] = 0; } } } vector<vector<string>> solveNQueens(int n) { f(n,0); return ans; } };
题目链接：单词搜索给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中，返回 true ；否则，返回 false 。单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。方法一：回溯class Solution { public: int dx[4] = {1,0,-1,0}; int dy[4] = {0,1,0,-1}; bool visited[20][20]; bool ans = false; void dfs(vector<vector<char>>& board, string word,int x,int y,int t) { if (t >= word.size()) { ans = true; return ; } if (x < 0 || x >= board.size() || y < 0 || y >= board[0].size() || visited[x][y]) return; if (board[x][y] != word[t]) return ; visited[x][y] = true; for (int i = 0;i < 4;i++) { int tx = x + dx[i]; int ty = y + dy[i]; dfs(board,word,tx,ty,t+1); } visited[x][y] = false; } bool exist(vector<vector<char>>& board, string word) { for (int i = 0;i < board.size();i++) { for (int j = 0;j < board[0].size();j++) { dfs(board,word,i,j,0); } } return ans; } };
题目链接：组合总和给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ，找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ，并以列表形式返回。你可以按 任意顺序 返回这些组合。candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同，则两种组合是不同的。 对于给定的输入，保证和为 target 的不同组合数少于 150 个。方法一：回溯class Solution { public: vector<vector<int>> ans; vector<int> t; void dfs(vector<int>& candidates,int target,int sum,int x) { if (sum == target) { ans.push_back(t); return ; }else if (sum > target) return ; if (x >= candidates.size()) return ; for (int i = x;i < candidates.size();i++) { t.push_back(candidates[i]); dfs(candidates,target,sum+candidates[i],i); t.pop_back(); } } vector<vector<int>> combinationSum(vector<int>& candidates, int target) { sort(candidates.begin(),candidates.end()); // 可去 dfs(candidates,target,0,0); return ans; } };
题目链接：电话号码的字母组合给定一个仅包含数字 2-9 的字符串，返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下（与电话按键相同）。注意 1 不对应任何字母。方法一：回溯class Solution { public: string list[10] = { "", // 0 "", // 1（不用） "abc", // 2 "def", // 3 "ghi", // 4 "jkl", // 5 "mno", // 6 "pqrs", // 7 "tuv", // 8 "wxyz" // 9 }; vector<string> ans; string t; void dfs(string digits,int x) { if (x >= digits.size()) { ans.push_back(t); return ; } for (int i = 0;i < list[digits[x]-'0'].size();i++) { t.push_back(list[digits[x]-'0'][i]); dfs(digits,x+1); t.pop_back(); } } vector<string> letterCombinations(string digits) { dfs(digits,0); return ans; } };
题目链接：子集给你一个整数数组 nums ，数组中的元素 互不相同 。返回该数组所有可能的子集（幂集）。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。方法一：回溯class Solution { public: vector<vector<int>> ans; vector<int> t; void f(vector<int>& nums,int x) { if (x >= nums.size()) { ans.push_back(t); return ; } t.push_back(nums[x]); f(nums,x+1); t.pop_back(); f(nums,x+1); } vector<vector<int>> subsets(vector<int>& nums) { f(nums,0); return ans; } };
题目链接：全排列给定一个不含重复数字的数组 nums ，返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。方法一：回溯class Solution { public: vector<vector<int>> ans; bool check[12]; vector<int> t; void f(vector<int>& nums,int x) { if (x >= nums.size()) { ans.push_back(t); return ; } for (int i = 0;i < nums.size();i++) { if (!check[i]) { check[i] = true; t.push_back(nums[i]); f(nums,x+1); t.pop_back(); check[i] = false; } } } vector<vector<int>> permute(vector<int>& nums) { memset(check, false, sizeof(check)); f(nums,0); return ans; } };